pax_global_header00006660000000000000000000000064132547407530014524gustar00rootroot0000000000000052 comment=8d2d1aa8e2870c05551dbdf870ba5c3b3b2cf052 catch-1.12.1/000077500000000000000000000000001325474075300126705ustar00rootroot00000000000000catch-1.12.1/.gitattributes000066400000000000000000000004551325474075300155670ustar00rootroot00000000000000# This sets the default behaviour, overriding core.autocrlf * text=auto # All source files should have unix line-endings in the repository, # but convert to native line-endings on checkout *.cpp text *.h text *.hpp text # Windows specific files should retain windows line-endings *.sln text eol=crlfcatch-1.12.1/.github/000077500000000000000000000000001325474075300142305ustar00rootroot00000000000000catch-1.12.1/.github/issue_template.md000066400000000000000000000014751325474075300176040ustar00rootroot00000000000000## Description ### Steps to reproduce ### Extra information * Catch version: **v42.42.42** * Operating System: **Joe's discount operating system** * Compiler+version: **Hidden Dragon v1.2.3** catch-1.12.1/.github/pull_request_template.md000066400000000000000000000020511325474075300211670ustar00rootroot00000000000000 ## Description ## GitHub Issues catch-1.12.1/.gitignore000066400000000000000000000007471325474075300146700ustar00rootroot00000000000000*.build *.pbxuser *.mode1v3 *.ncb *.suo Debug Release *.user *.xcuserstate .DS_Store xcuserdata CatchSelfTest.xcscheme Breakpoints.xcbkptlist projects/VS2010/TestCatch/_UpgradeReport_Files/ projects/VS2010/TestCatch/TestCatch/TestCatch.vcxproj.filters projects/VisualStudio/TestCatch/UpgradeLog.XML projects/CMake/.idea projects/CMake/cmake-build-debug UpgradeLog.XML Resources/DWARF projects/Generated *.pyc DerivedData *.xccheckout Build .idea cmake-build-debug cmake-build-release .vscatch-1.12.1/.travis.yml000066400000000000000000000145411325474075300150060ustar00rootroot00000000000000language: cpp sudo: false matrix: include: # 1/ Linux Clang Builds - os: linux compiler: clang addons: &clang34 apt: sources: ['llvm-toolchain-precise', 'ubuntu-toolchain-r-test'] packages: ['clang'] env: COMPILER='clang++' BUILD_TYPE='Release' - os: linux compiler: clang addons: *clang34 env: COMPILER='clang++' BUILD_TYPE='Debug' - os: linux compiler: clang addons: &clang35 apt: sources: ['llvm-toolchain-precise-3.5', 'ubuntu-toolchain-r-test'] packages: ['clang-3.5'] env: COMPILER='clang++-3.5' BUILD_TYPE='Release' - os: linux compiler: clang addons: *clang35 env: COMPILER='clang++-3.5' BUILD_TYPE='Debug' - os: linux compiler: clang addons: &clang36 apt: sources: ['llvm-toolchain-precise-3.6', 'ubuntu-toolchain-r-test'] packages: ['clang-3.6'] env: COMPILER='clang++-3.6' BUILD_TYPE='Release' - os: linux compiler: clang addons: *clang36 env: COMPILER='clang++-3.6' BUILD_TYPE='Debug' - os: linux compiler: clang addons: &clang37 apt: sources: ['llvm-toolchain-precise-3.7', 'ubuntu-toolchain-r-test'] packages: ['clang-3.7'] env: COMPILER='clang++-3.7' BUILD_TYPE='Release' - os: linux compiler: clang addons: *clang37 env: COMPILER='clang++-3.7' BUILD_TYPE='Debug' - os: linux compiler: clang addons: &clang38 apt: sources: ['llvm-toolchain-precise-3.8', 'ubuntu-toolchain-r-test'] packages: ['clang-3.8'] env: COMPILER='clang++-3.8' BUILD_TYPE='Release' - os: linux compiler: clang addons: *clang38 env: COMPILER='clang++-3.8' BUILD_TYPE='Debug' # 2/ Linux GCC Builds - os: linux compiler: gcc addons: &gcc44 apt: sources: ['ubuntu-toolchain-r-test'] packages: ['g++-4.4'] env: COMPILER='g++-4.4' BUILD_TYPE='Release' - os: linux compiler: gcc addons: *gcc44 env: COMPILER='g++-4.4' BUILD_TYPE='Debug' - os: linux compiler: gcc addons: &gcc47 apt: sources: ['ubuntu-toolchain-r-test'] packages: ['g++-4.7'] env: COMPILER='g++-4.7' BUILD_TYPE='Release' - os: linux compiler: gcc addons: *gcc47 env: COMPILER='g++-4.7' BUILD_TYPE='Debug' - os: linux compiler: gcc addons: &gcc48 apt: sources: ['ubuntu-toolchain-r-test'] packages: ['g++-4.8'] env: COMPILER='g++-4.8' BUILD_TYPE='Release' - os: linux compiler: gcc addons: *gcc48 env: COMPILER='g++-4.8' BUILD_TYPE='Debug' - os: linux compiler: gcc addons: &gcc49 apt: sources: ['ubuntu-toolchain-r-test'] packages: ['g++-4.9'] env: COMPILER='g++-4.9' BUILD_TYPE='Release' - os: linux compiler: gcc addons: *gcc49 env: COMPILER='g++-4.9' BUILD_TYPE='Debug' - os: linux compiler: gcc addons: &gcc5 apt: sources: ['ubuntu-toolchain-r-test'] packages: ['g++-5'] env: COMPILER='g++-5' BUILD_TYPE='Release' - os: linux compiler: gcc addons: *gcc5 env: COMPILER='g++-5' BUILD_TYPE='Debug' - os: linux compiler: gcc addons: &gcc6 apt: sources: ['ubuntu-toolchain-r-test'] packages: ['g++-6'] env: COMPILER='g++-6' BUILD_TYPE='Release' - os: linux compiler: gcc addons: *gcc6 env: COMPILER='g++-6' BUILD_TYPE='Debug' # 3a/ Linux C++11 GCC builds - os: linux compiler: gcc addons: *gcc48 env: COMPILER='g++-4.8' BUILD_TYPE='Release' CPP11=1 - os: linux compiler: gcc addons: *gcc48 env: COMPILER='g++-4.8' BUILD_TYPE='Debug' CPP11=1 # 3b/ Linux C++11 Clang builds - os: linux compiler: clang addons: *clang38 env: COMPILER='clang++-3.8' BUILD_TYPE='Release' CPP11=1 - os: linux compiler: clang addons: *clang38 env: COMPILER='clang++-3.8' BUILD_TYPE='Debug' CPP11=1 # 4a/ Linux C++14 GCC builds - os: linux compiler: gcc addons: *gcc6 env: COMPILER='g++-6' BUILD_TYPE='Release' CPP14=1 - os: linux compiler: gcc addons: *gcc6 env: COMPILER='g++-6' BUILD_TYPE='Debug' CPP14=1 # 4b/ Linux C++14 Clang builds # - os: linux # compiler: clang # addons: *clang38 # env: COMPILER='clang++-3.8' BUILD_TYPE='Release' CPP14=1 # # - os: linux # compiler: clang # addons: *clang38 # env: COMPILER='clang++-3.8' BUILD_TYPE='Debug' CPP14=1 # 5/ OSX Clang Builds - os: osx osx_image: xcode7.3 compiler: clang env: COMPILER='clang++' BUILD_TYPE='Debug' - os: osx osx_image: xcode7.3 compiler: clang env: COMPILER='clang++' BUILD_TYPE='Release' - os: osx osx_image: xcode8 compiler: clang env: COMPILER='clang++' BUILD_TYPE='Debug' - os: osx osx_image: xcode8 compiler: clang env: COMPILER='clang++' BUILD_TYPE='Release' - os: osx osx_image: xcode8 compiler: clang env: COMPILER='clang++' BUILD_TYPE='Debug' USE_CPP11=1 - os: osx osx_image: xcode8 compiler: clang env: COMPILER='clang++' BUILD_TYPE='Release' USE_CPP11=1 - os: osx osx_image: xcode8 compiler: clang env: COMPILER='clang++' BUILD_TYPE='Debug' USE_CPP14=1 - os: osx osx_image: xcode8 compiler: clang env: COMPILER='clang++' BUILD_TYPE='Release' USE_CPP14=1 install: - DEPS_DIR="${TRAVIS_BUILD_DIR}/deps" - mkdir -p ${DEPS_DIR} && cd ${DEPS_DIR} - | if [[ "${TRAVIS_OS_NAME}" == "linux" ]]; then CMAKE_URL="http://www.cmake.org/files/v3.3/cmake-3.3.2-Linux-x86_64.tar.gz" mkdir cmake && travis_retry wget --no-check-certificate --quiet -O - ${CMAKE_URL} | tar --strip-components=1 -xz -C cmake export PATH=${DEPS_DIR}/cmake/bin:${PATH} elif [[ "${TRAVIS_OS_NAME}" == "osx" ]]; then which cmake || brew install cmake fi before_script: - export CXX=${COMPILER} - cd ${TRAVIS_BUILD_DIR} - cmake -H. -BBuild -DCMAKE_BUILD_TYPE=${BUILD_TYPE} -Wdev -DUSE_CPP11=${CPP11} -DUSE_CPP14=${CPP14} - cd Build script: - make -j 2 - ctest -V -j 2 catch-1.12.1/CMakeLists.txt000066400000000000000000000277031325474075300154410ustar00rootroot00000000000000cmake_minimum_required(VERSION 3.0) project(CatchSelfTest) set_property(GLOBAL PROPERTY USE_FOLDERS ON) # define some folders set(CATCH_DIR ${CMAKE_CURRENT_SOURCE_DIR}) set(SELF_TEST_DIR ${CATCH_DIR}/projects/SelfTest) set(BENCHMARK_DIR ${CATCH_DIR}/projects/Benchmark) set(HEADER_DIR ${CATCH_DIR}/include) if(USE_CPP11) ## We can't turn this on by default, since it breaks on travis message(STATUS "Enabling C++11") set(CMAKE_CXX_FLAGS "-std=c++11 ${CMAKE_CXX_FLAGS}") elseif(USE_CPP14) message(STATUS "Enabling C++14") set(CMAKE_CXX_FLAGS "-std=c++14 ${CMAKE_CXX_FLAGS}") endif() if(USE_WMAIN) set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} /ENTRY:wmainCRTStartup") endif() #checks that the given hard-coded list contains all headers + sources in the given folder function(CheckFileList LIST_VAR FOLDER) set(MESSAGE " should be added to the variable ${LIST_VAR}") set(MESSAGE "${MESSAGE} in ${CMAKE_CURRENT_LIST_FILE}\n") file(GLOB GLOBBED_LIST "${FOLDER}/*.cpp" "${FOLDER}/*.hpp" "${FOLDER}/*.h") list(REMOVE_ITEM GLOBBED_LIST ${${LIST_VAR}}) foreach(EXTRA_ITEM ${GLOBBED_LIST}) string(REPLACE "${CATCH_DIR}/" "" RELATIVE_FILE_NAME "${EXTRA_ITEM}") message(AUTHOR_WARNING "The file \"${RELATIVE_FILE_NAME}\"${MESSAGE}") endforeach() endfunction() function(CheckFileListRec LIST_VAR FOLDER) set(MESSAGE " should be added to the variable ${LIST_VAR}") set(MESSAGE "${MESSAGE} in ${CMAKE_CURRENT_LIST_FILE}\n") file(GLOB_RECURSE GLOBBED_LIST "${FOLDER}/*.cpp" "${FOLDER}/*.hpp" "${FOLDER}/*.h") list(REMOVE_ITEM GLOBBED_LIST ${${LIST_VAR}}) foreach(EXTRA_ITEM ${GLOBBED_LIST}) string(REPLACE "${CATCH_DIR}/" "" RELATIVE_FILE_NAME "${EXTRA_ITEM}") message(AUTHOR_WARNING "The file \"${RELATIVE_FILE_NAME}\"${MESSAGE}") endforeach() endfunction() # define the sources of the self test # Please keep these ordered alphabetically set(TEST_SOURCES ${SELF_TEST_DIR}/ApproxTests.cpp ${SELF_TEST_DIR}/BDDTests.cpp ${SELF_TEST_DIR}/ClassTests.cpp ${SELF_TEST_DIR}/CmdLineTests.cpp ${SELF_TEST_DIR}/CompilationTests.cpp ${SELF_TEST_DIR}/ConditionTests.cpp ${SELF_TEST_DIR}/DecompositionTests.cpp ${SELF_TEST_DIR}/EnumToString.cpp ${SELF_TEST_DIR}/ExceptionTests.cpp ${SELF_TEST_DIR}/GeneratorTests.cpp ${SELF_TEST_DIR}/MessageTests.cpp ${SELF_TEST_DIR}/MiscTests.cpp ${SELF_TEST_DIR}/PartTrackerTests.cpp ${SELF_TEST_DIR}/TagAliasTests.cpp ${SELF_TEST_DIR}/TestMain.cpp ${SELF_TEST_DIR}/ToStringGeneralTests.cpp ${SELF_TEST_DIR}/ToStringPair.cpp ${SELF_TEST_DIR}/ToStringTuple.cpp ${SELF_TEST_DIR}/ToStringVector.cpp ${SELF_TEST_DIR}/ToStringWhich.cpp ${SELF_TEST_DIR}/TrickyTests.cpp ${SELF_TEST_DIR}/VariadicMacrosTests.cpp ${SELF_TEST_DIR}/MatchersTests.cpp ) CheckFileList(TEST_SOURCES ${SELF_TEST_DIR}) # A set of impl files that just #include a single header # Please keep these ordered alphabetically set(IMPL_SOURCES ${SELF_TEST_DIR}/SurrogateCpps/catch_common.cpp ${SELF_TEST_DIR}/SurrogateCpps/catch_console_colour.cpp ${SELF_TEST_DIR}/SurrogateCpps/catch_debugger.cpp ${SELF_TEST_DIR}/SurrogateCpps/catch_interfaces_capture.cpp ${SELF_TEST_DIR}/SurrogateCpps/catch_interfaces_config.cpp ${SELF_TEST_DIR}/SurrogateCpps/catch_interfaces_exception.cpp ${SELF_TEST_DIR}/SurrogateCpps/catch_interfaces_generators.cpp ${SELF_TEST_DIR}/SurrogateCpps/catch_interfaces_registry_hub.cpp ${SELF_TEST_DIR}/SurrogateCpps/catch_interfaces_reporter.cpp ${SELF_TEST_DIR}/SurrogateCpps/catch_interfaces_runner.cpp ${SELF_TEST_DIR}/SurrogateCpps/catch_interfaces_testcase.cpp ${SELF_TEST_DIR}/SurrogateCpps/catch_message.cpp ${SELF_TEST_DIR}/SurrogateCpps/catch_option.cpp ${SELF_TEST_DIR}/SurrogateCpps/catch_ptr.cpp ${SELF_TEST_DIR}/SurrogateCpps/catch_stream.cpp ${SELF_TEST_DIR}/SurrogateCpps/catch_streambuf.cpp ${SELF_TEST_DIR}/SurrogateCpps/catch_test_spec.cpp ${SELF_TEST_DIR}/SurrogateCpps/catch_xmlwriter.cpp ${SELF_TEST_DIR}/SurrogateCpps/catch_test_case_tracker.cpp ) CheckFileList(IMPL_SOURCES ${SELF_TEST_DIR}/SurrogateCpps) # Please keep these ordered alphabetically set(TOP_LEVEL_HEADERS ${HEADER_DIR}/catch.hpp ${HEADER_DIR}/catch_session.hpp ${HEADER_DIR}/catch_with_main.hpp ) CheckFileList(TOP_LEVEL_HEADERS ${HEADER_DIR}) # Please keep these ordered alphabetically set(EXTERNAL_HEADERS ${HEADER_DIR}/external/clara.h ${HEADER_DIR}/external/tbc_text_format.h ) CheckFileList(EXTERNAL_HEADERS ${HEADER_DIR}/external) # Please keep these ordered alphabetically set(INTERNAL_HEADERS ${HEADER_DIR}/internal/catch_approx.hpp ${HEADER_DIR}/internal/catch_assertionresult.h ${HEADER_DIR}/internal/catch_assertionresult.hpp ${HEADER_DIR}/internal/catch_capture.hpp ${HEADER_DIR}/internal/catch_clara.h ${HEADER_DIR}/internal/catch_commandline.hpp ${HEADER_DIR}/internal/catch_common.h ${HEADER_DIR}/internal/catch_common.hpp ${HEADER_DIR}/internal/catch_compiler_capabilities.h ${HEADER_DIR}/internal/catch_config.hpp ${HEADER_DIR}/internal/catch_console_colour.hpp ${HEADER_DIR}/internal/catch_console_colour_impl.hpp ${HEADER_DIR}/internal/catch_context.h ${HEADER_DIR}/internal/catch_context_impl.hpp ${HEADER_DIR}/internal/catch_debugger.h ${HEADER_DIR}/internal/catch_debugger.hpp ${HEADER_DIR}/internal/catch_default_main.hpp ${HEADER_DIR}/internal/catch_errno_guard.hpp ${HEADER_DIR}/internal/catch_evaluate.hpp ${HEADER_DIR}/internal/catch_exception_translator_registry.hpp ${HEADER_DIR}/internal/catch_expression_lhs.hpp ${HEADER_DIR}/internal/catch_fatal_condition.hpp ${HEADER_DIR}/internal/catch_generators.hpp ${HEADER_DIR}/internal/catch_generators_impl.hpp ${HEADER_DIR}/internal/catch_impl.hpp ${HEADER_DIR}/internal/catch_interfaces_capture.h ${HEADER_DIR}/internal/catch_interfaces_config.h ${HEADER_DIR}/internal/catch_interfaces_exception.h ${HEADER_DIR}/internal/catch_interfaces_generators.h ${HEADER_DIR}/internal/catch_interfaces_registry_hub.h ${HEADER_DIR}/internal/catch_interfaces_reporter.h ${HEADER_DIR}/internal/catch_interfaces_runner.h ${HEADER_DIR}/internal/catch_interfaces_tag_alias_registry.h ${HEADER_DIR}/internal/catch_interfaces_testcase.h ${HEADER_DIR}/internal/catch_legacy_reporter_adapter.h ${HEADER_DIR}/internal/catch_legacy_reporter_adapter.hpp ${HEADER_DIR}/internal/catch_list.hpp ${HEADER_DIR}/internal/catch_matchers.hpp ${HEADER_DIR}/internal/catch_matchers_string.h ${HEADER_DIR}/internal/catch_matchers_string.hpp ${HEADER_DIR}/internal/catch_matchers_vector.h ${HEADER_DIR}/internal/catch_message.h ${HEADER_DIR}/internal/catch_message.hpp ${HEADER_DIR}/internal/catch_notimplemented_exception.h ${HEADER_DIR}/internal/catch_notimplemented_exception.hpp ${HEADER_DIR}/internal/catch_objc.hpp ${HEADER_DIR}/internal/catch_objc_arc.hpp ${HEADER_DIR}/internal/catch_option.hpp ${HEADER_DIR}/internal/catch_platform.h ${HEADER_DIR}/internal/catch_ptr.hpp ${HEADER_DIR}/internal/catch_reenable_warnings.h ${HEADER_DIR}/internal/catch_registry_hub.hpp ${HEADER_DIR}/internal/catch_reporter_registrars.hpp ${HEADER_DIR}/internal/catch_reporter_registry.hpp ${HEADER_DIR}/internal/catch_result_builder.h ${HEADER_DIR}/internal/catch_result_builder.hpp ${HEADER_DIR}/internal/catch_result_type.h ${HEADER_DIR}/internal/catch_run_context.hpp ${HEADER_DIR}/internal/catch_section.h ${HEADER_DIR}/internal/catch_section.hpp ${HEADER_DIR}/internal/catch_section_info.h ${HEADER_DIR}/internal/catch_section_info.hpp ${HEADER_DIR}/internal/catch_stream.h ${HEADER_DIR}/internal/catch_stream.hpp ${HEADER_DIR}/internal/catch_streambuf.h ${HEADER_DIR}/internal/catch_suppress_warnings.h ${HEADER_DIR}/internal/catch_tag_alias.h ${HEADER_DIR}/internal/catch_tag_alias_registry.h ${HEADER_DIR}/internal/catch_tag_alias_registry.hpp ${HEADER_DIR}/internal/catch_test_case_info.h ${HEADER_DIR}/internal/catch_test_case_info.hpp ${HEADER_DIR}/internal/catch_test_case_registry_impl.hpp ${HEADER_DIR}/internal/catch_test_case_tracker.hpp ${HEADER_DIR}/internal/catch_test_registry.hpp ${HEADER_DIR}/internal/catch_test_spec.hpp ${HEADER_DIR}/internal/catch_test_spec_parser.hpp ${HEADER_DIR}/internal/catch_text.h ${HEADER_DIR}/internal/catch_timer.h ${HEADER_DIR}/internal/catch_timer.hpp ${HEADER_DIR}/internal/catch_tostring.h ${HEADER_DIR}/internal/catch_tostring.hpp ${HEADER_DIR}/internal/catch_totals.hpp ${HEADER_DIR}/internal/catch_type_traits.hpp ${HEADER_DIR}/internal/catch_version.h ${HEADER_DIR}/internal/catch_version.hpp ${HEADER_DIR}/internal/catch_wildcard_pattern.hpp ${HEADER_DIR}/internal/catch_windows_h_proxy.h ${HEADER_DIR}/internal/catch_xmlwriter.hpp ) CheckFileList(INTERNAL_HEADERS ${HEADER_DIR}/internal) # Please keep these ordered alphabetically set(REPORTER_HEADERS ${HEADER_DIR}/reporters/catch_reporter_automake.hpp ${HEADER_DIR}/reporters/catch_reporter_bases.hpp ${HEADER_DIR}/reporters/catch_reporter_compact.hpp ${HEADER_DIR}/reporters/catch_reporter_console.hpp ${HEADER_DIR}/reporters/catch_reporter_junit.hpp ${HEADER_DIR}/reporters/catch_reporter_multi.hpp ${HEADER_DIR}/reporters/catch_reporter_tap.hpp ${HEADER_DIR}/reporters/catch_reporter_teamcity.hpp ${HEADER_DIR}/reporters/catch_reporter_xml.hpp ) CheckFileList(REPORTER_HEADERS ${HEADER_DIR}/reporters) # Specify the headers, too, so CLion recognises them as project files set(HEADERS ${TOP_LEVEL_HEADERS} ${EXTERNAL_HEADERS} ${INTERNAL_HEADERS} ${REPORTER_HEADERS} ) set(BENCH_SOURCES ${BENCHMARK_DIR}/BenchMain.cpp ${BENCHMARK_DIR}/StringificationBench.cpp ) CheckFileList(BENCH_SOURCES ${BENCHMARK_DIR}) # Provide some groupings for IDEs SOURCE_GROUP("Tests" FILES ${TEST_SOURCES}) SOURCE_GROUP("Surrogates" FILES ${IMPL_SOURCES}) SOURCE_GROUP("Benchmarks" FILES ${BENCH_SOURCES}) # configure the executable include_directories(${HEADER_DIR}) # Projects consuming Catch via ExternalProject_Add might want to use install step # without building all of our selftests. if (NOT NO_SELFTEST) add_executable(SelfTest ${TEST_SOURCES} ${IMPL_SOURCES} ${HEADERS}) add_executable(Benchmark ${BENCH_SOURCES} ${HEADERS}) # Add desired warnings if ( CMAKE_CXX_COMPILER_ID MATCHES "Clang|AppleClang|GNU" ) target_compile_options( SelfTest PRIVATE -Wall -Wextra ) target_compile_options( Benchmark PRIVATE -Wall -Wextra ) endif() if ( CMAKE_CXX_COMPILER_ID MATCHES "MSVC" ) target_compile_options( SelfTest PRIVATE /W4 /w44265 /WX ) target_compile_options( Benchmark PRIVATE /W4 ) endif() # configure unit tests via CTest enable_testing() add_test(NAME RunTests COMMAND SelfTest) add_test(NAME ListTests COMMAND SelfTest --list-tests) set_tests_properties(ListTests PROPERTIES PASS_REGULAR_EXPRESSION "[0-9]+ test cases") add_test(NAME ListTags COMMAND SelfTest --list-tags) set_tests_properties(ListTags PROPERTIES PASS_REGULAR_EXPRESSION "[0-9]+ tags") endif() # !NO_SELFTEST install(DIRECTORY "single_include/" DESTINATION "include/catch") catch-1.12.1/CODE_OF_CONDUCT.md000066400000000000000000000062171325474075300154750ustar00rootroot00000000000000# Contributor Covenant Code of Conduct ## Our Pledge In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, gender identity and expression, level of experience, nationality, personal appearance, race, religion, or sexual identity and orientation. ## Our Standards Examples of behavior that contributes to creating a positive environment include: * Using welcoming and inclusive language * Being respectful of differing viewpoints and experiences * Gracefully accepting constructive criticism * Focusing on what is best for the community * Showing empathy towards other community members Examples of unacceptable behavior by participants include: * The use of sexualized language or imagery and unwelcome sexual attention or advances * Trolling, insulting/derogatory comments, and personal or political attacks * Public or private harassment * Publishing others' private information, such as a physical or electronic address, without explicit permission * Other conduct which could reasonably be considered inappropriate in a professional setting ## Our Responsibilities Project maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior. Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful. ## Scope This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. Examples of representing a project or community include using an official project e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. Representation of a project may be further defined and clarified by project maintainers. ## Enforcement Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at github@philnash.me. The project team will review and investigate all complaints, and will respond in a way that it deems appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately. Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership. ## Attribution This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, available at [http://contributor-covenant.org/version/1/4][version] [homepage]: http://contributor-covenant.org [version]: http://contributor-covenant.org/version/1/4/ catch-1.12.1/LICENSE.txt000066400000000000000000000024721325474075300145200ustar00rootroot00000000000000Boost Software License - Version 1.0 - August 17th, 2003 Permission is hereby granted, free of charge, to any person or organization obtaining a copy of the software and accompanying documentation covered by this license (the "Software") to use, reproduce, display, distribute, execute, and transmit the Software, and to prepare derivative works of the Software, and to permit third-parties to whom the Software is furnished to do so, all subject to the following: The copyright notices in the Software and this entire statement, including the above license grant, this restriction and the following disclaimer, must be included in all copies of the Software, in whole or in part, and all derivative works of the Software, unless such copies or derivative works are solely in the form of machine-executable object code generated by a source language processor. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. catch-1.12.1/README.md000066400000000000000000000033551325474075300141550ustar00rootroot00000000000000![catch logo](catch-logo-small.png) [![Github Releases](https://img.shields.io/github/release/philsquared/catch.svg)](https://github.com/philsquared/catch/releases) [![Build Status](https://travis-ci.org/philsquared/Catch.svg?branch=master)](https://travis-ci.org/philsquared/Catch) [![Build status](https://ci.appveyor.com/api/projects/status/hrtk60hv6tw6fght/branch/master?svg=true)](https://ci.appveyor.com/project/philsquared/catch/branch/master) [![Try online](https://img.shields.io/badge/try-online-blue.svg)](https://wandbox.org/permlink/q3wLegtaHunTHSls) The latest, single header, version can be downloaded directly using this link ## What's the Catch? Catch stands for C++ Automated Test Cases in Headers and is a multi-paradigm automated test framework for C++ and Objective-C (and, maybe, C). It is implemented entirely in a set of header files, but is packaged up as a single header for extra convenience. ## How to use it This documentation comprises these three parts: * [Why do we need yet another C++ Test Framework?](docs/why-catch.md) * [Tutorial](docs/tutorial.md) - getting started * [Reference section](docs/Readme.md) - all the details ## More * Issues and bugs can be raised on the [Issue tracker on GitHub](https://github.com/philsquared/Catch/issues) * For discussion or questions please use [the dedicated Google Groups forum](https://groups.google.com/forum/?fromgroups#!forum/catch-forum) * See [who else is using Catch](docs/opensource-users.md) ## Help us out We're currently running [a survey](https://www.surveymonkey.co.uk/r/TLLYQJW) to help us shape the future of Catch. Please take a few moments to fill it out (there's only ten questions). catch-1.12.1/appveyor.yml000066400000000000000000000031011325474075300152530ustar00rootroot00000000000000# version string format -- This will be overwritten later anyway version: "{build}" os: - Visual Studio 2017 - Visual Studio 2015 - Visual Studio 2013 environment: matrix: - additional_flags: "/permissive- /std:c++latest" wmain: 0 - additional_flags: "" wmain: 0 - additional_flags: "/D_UNICODE /DUNICODE" wmain: 1 matrix: exclude: - additional_flags: "/permissive- /std:c++latest" os: Visual Studio 2015 - additional_flags: "/permissive- /std:c++latest" os: Visual Studio 2013 init: - git config --global core.autocrlf input # Set build version to git commit-hash - ps: Update-AppveyorBuild -Version "$($env:APPVEYOR_REPO_BRANCH) - $($env:APPVEYOR_REPO_COMMIT)" # fetch repository as zip archive shallow_clone: true # Win32 and x64 are CMake-compatible solution platform names. # This allows us to pass %PLATFORM% to CMake -A. platform: - Win32 - x64 # build Configurations, i.e. Debug, Release, etc. configuration: - Debug - Release #Cmake will autodetect the compiler, but we set the arch before_build: - set CXXFLAGS=%additional_flags% - cmake -H. -BBuild -A%PLATFORM% -DUSE_WMAIN=%wmain% # build with MSBuild build: project: Build\CatchSelfTest.sln # path to Visual Studio solution or project parallel: true # enable MSBuild parallel builds verbosity: normal # MSBuild verbosity level {quiet|minimal|normal|detailed} test_script: - cd Build - ctest -V -j 2 -C %CONFIGURATION% catch-1.12.1/catch-hand-icon.png000066400000000000000000001471301325474075300163240ustar00rootroot00000000000000PNG  IHDR2oL?gAMA a@IDATx nS;qT"2"IIJBЀ2Bd̐yٽ~s99ﰇ5|;|g= hiaiNii6i4Tz[zEzYz^zBz\zXzS@@Լ}6@(|u=ҪS5Vg:)oh+륷$  @  ZJߑ| ?])SϪ3-$  @ A 8E y2XOi?( @zp S.0OFI@ @ sw/N:ޫ'@ @ӗR'uD @'/_)j/c$  @ yғRQ!+y5  @ 9eaҋRHewѬ,Q @  /=equ3#&C @ [B})'0.^'Q@ @ `3˶}gNsO( @@`ʞJ @ @ k:.b1/Ly@ @`l8[bn[@0 @YU^")u_ĶGlD @*$8.V0^l @<@(hUrT*ŒX-cq@Ki  AF}%?tO`@i{x@%X](Xvr~_@LXL-q#y $G'2Ʌ N`mxiҷu< ȴƉ @ј]~%],qSnFRn@ ~1"0 ]@) Fuh@?Z> WB#Q"p_X`  е,` , Zڨ QxMV .d2 4nBJ`]vWE 4 @ Pw%ĻaVyO@ Df8|@ ʏӤ&On#_HI @@З}RV( @ȖݔH)f+C dO`f8A&.(f g @Ȓ(y}EL| >e4 @@6%.bcpT @ , +Z9 _tYb,w[ @C^)L Pf7} @ GwH\l9&.>C K`+>Q"&Ng+v#M_< @ȍ9]/N"&>ۡH @@<| 8'qWK$  @!<0]bil2G!@ t01xLqV@ @ +%.bb'g?( P2,0ChZBmNMOf z 7BŤj^]Ei1$E鱗ѩzX=B` Q'O#t/c% R P&|IiEiyiEKUy?^z@goϬ8A@\T@ON~ }c24gʠ'B3 { 0B^eZIWfB.~st'HJ@#09Ob?#%@ 8d߫'2q08Y;¼0 Y{I^fpm,Q @'XL ][۳9Yeg{Sb _Ō P @eEߕ8 E/Q 0{/p QlFK@ $0:C(l%ئ@/UbB۞<. @W\.1>I$)\/(>MɇO`}sjUx @hlZ2mϲ텕#&l?Uz]bʃ9%  @=,yY^'J(F~!%mt f]@ 08Wa0 _+~K:wn`,Rb  @"ql֗(pίHJo0,^^z+@țr3 vz],w&OF&Hc0h'# @`0oH ּ&6L tLSBRl8"Oʴ9e?χ@(UzT:zbQ ܸRb߀AY9@@GÇ7wT7J0* ,EmRUV:k{d3/džm[%rU}yfxinl(r"0V^!-ӑzd$bfoǝ Q P5 ۫6͖!TN`9m"iʷ"&2B|,w!F:X>F@sl PUUSRVLV/#Y -[$d> TD`-m@SbqbD2\AH9rF'X @Mg `-ON8$m{b?ړP۰` @-[hi$ԃnvxlVY8Ȉˤs㈻oX1a6@@S $NBaJב* ]b?A9p@;ۂ E M)oNdxNcrQ|7~* TL`/mH1;F(K%#Đ)WI@@!c8b㋊QgT>-W(y S.@@?pܥx,uFaHuY1/b( |WtNs9ΨwW]ҋDF 5D% `a?iH}~s x@8Rx NfQ;aqyWfDv %;GK)^ӵŨx)yós s1i+@PYa9 ΨtkDs 実%Q @QE̩Rl4;Ix ۝)~A@@|sĉL "nO`cLRZbvA@@xIٹJ)y_(&x͓x%$  @ 9Ed^S'R"9N, Ly8;A@@Z|s95{U I+f<ovLP2 $_Ĝ$qRS/̰xD)o c4\@%Ĝ(rNN0,)3ΗR7|J37)_*q3D( >_Ĝ qbSOۻQI}u:v̆@ |"]~Pɕ.O鶲aXS'\ʁgH#  @ +KEX=o'!@YI6IL=/_䩿) &_$ 2`Zܮ<@ZJ@ 0w;vAMMm_.wOPNPbо P @3_pbS=G}U[ )'Q @hB`o};7(5 WG` mA)bJI<  @` KNhew|y]%Fk+$aPgLP }QT(@@+vB΃xn۾SWi%8,S߷[o1NwH @ ѲoJTw]fxJ}զ=ysifL lu-O=P;zKxIRx  @  k#HEԩ/?BUmK}V܄AQ9ౄgK[KJ@*$0uTԁz/TS6՛!>>WK>%=T( :̮^-q2SRumC`m 8 wEvIn7) H/]HκR {ggwv)Ӥe4[7Yҽٍi)|ƿi gʛWYDB&0*%`wJK>P%3+\cڃ2.y7(('>]msM!uR<sS5A<] :<&)bBSb8vZ˲ZtyM@OO럳%_\%6U,)Nivұ9 _0USR0 `B!2Ji- 7eҷ%T/vT=P8Q+b3R yS}{ \&Rm гaDE`QY뻒:LcoY(A(y0SQ= ?-].yڅ0<S tLKcτmYsw'"wghi ?{JK .w+fI@mXVk<#bH۴YH> t_ON?.$Q ` II'KOs$  `pAu~. &+emMGrE0!X[-)bb^"@U20uI1ЀTl~ ;i_Jt+{/~_~V:KzV =xo!Q KOΕhx[gpx-/M>gzZ"oa;MhDɗK#]'%6u@GN\x wäޯ~[UOJ@.KgHLk/| KL'h`rwj `WJ9[>o $^'e?]!1?m`ޅ' C`S}6YFÏ݅Rkt%}-Z!q|A9y Ȝ*E$$J=FZa5p{r.1P(@FE)ƪ.['׳s!'Bq~;FDɇ5?g:_((@FՀ\E'W ,M^,_)/Dɇr/^Sg|+/)*@`w9I#=89G[h]~Y;<¤rK(,@(@6$-F#υPpOqM}ϒ֓(yXNn/\7ab^<"̘dib1Dj NBlϷ$ި-Qҍ BρהH@ Aʧ{;^)ArZ2si3S ʙ2Ob9 B/&$m,/Bű]W:Qrc$B`Syĭڄ_A[yzxxå%%JJHk0H97  ,rm֩bELɾ9yĉ䭊Y ?[<O\́+ Pzݛ߁%%`ĵ;/}M.>}}MP x RPi KvG),mSB?&3_D(~ʅw 1g+B Qi_e֧aU*yCZKgңᛋm[FE h4 /ߑrso.Ѧ$'+'|?3Q"1}J^ha@΁-_P  )ݻA_'>@71ryouAH,")#h& 1ƭ|YdBN{X]!ﮙ>r`𱞆(̲\w(} <־C""l͡qfbgN:sQ?.q#?q9PzXb_9y\HȆSex,JA}sb J:~K c_w+XmN'H(DڗO <@R.?DnN*Q'|ESb9P\\ȇHzD#?I8^lY!|8QzY݆9Plɲ~\w3xB\f(q!4}@y9kMC /],TەU%lDI`AU׫}uӌ1EK`-UDܗ8ro3U"WO~)qXU,&FÀ(?Ծq_(pb㗂R#'oJa%-%Q%0Lo%].o.N>D@}h$2sEXMd?Ƚ\&M2҃ ȁrD""plqY<8f.{0W,?[`o/_J>V>Avr`J@ ";vv\}A\V(: X%9qLdiYGv/K`B%总5{,K@ "+W$ <@C16S7K]w b_HI'wЎAOA"#;H4}ddC]]1[G/{|RmC؆Y_@>kRTAT}\G`!]iJ>)'0@@15>UzjA me])Q"=N/w:/c` xPfp0XZJ( ;]B\\s%rog?aY8O@D!^myqhnPM;=K&-|9PMՒI4D#r.hX{3xJL(p/2>W'I";?&["a@/i?X:X͞$  8? |^{3kL&;Z :m-R1f9Xg6TJ z8>=AҦ҂R2ų{P r pMN^Ky4or VP% =}$w@ <# {B&…Lű@nTĞx^FOr'J15w|G]N|w&.`Œ VCO}~1-ɪ8=pl<.1{@61әt n+`}_&ew(\D,LҴi=N@4Gf#f."lސȳ<+FJ oHOK3 ŕ7wHgHNH@\f~1 W3|>bH~iW'%r9oB($)-@Vbz.&te-.-=Hwr:뫟Prj*ۃK~SxeyŖ(ϯW)"鄯bkd˴׏'T\E~ y, Oa˹"k$CJwKe; ߺreVz4L@a3NqG-#ܿ&3;K77I!UD\:?H %_S DG`YIc:b[[Ϙp×e9|'%BX@  >Ddp]8ab44PaEH. b_UD $?F`2=6Hg{+3V1}جROXw~Q̹S~Iz{Q@6z\*_ -[} C`AuR!gSBw{FK@XC!`ab1P㾈9F#o1qٰ8TYUǁ'[=/|R:RNb P L#0O8Kb48/b5@dYhRvW+ PAĔǂ@ ЌΆ;m' p>~e,Xi#I!CؒON"3Oe!>}( ΁ ʫHKHO@,>ݐZ߳bTY3zv!JQw}\brOwx"@UXWqCq M6~A>ڟ֟nCnM}}t>) P͇$fS|ɧO>>GX;v䀟9VK@Y=u wR̍N|=q0?~>)=(X(B$Yjr,ReȧOO%Sk{.RmucwA:BBO@@}A`e9w a1fޯ:|bJ> ܸZA@0{_#g߃5)V-oQqI4~ɒ>˓^!}Or[?D ,9OayGΉcq8,Jo|Yz^]zbRY)kՖ߭+}RZ@@@f'y,E~y_$TjZ6)׶+'=2&0|J9zPyЭ˩3#SJu<ٯf4/VJ@;OƟa9%CRy@wD:%}uWY)׼KWsr+ >J`تo}I 'NU֩-| JuޭMKJ-rc+,-.Q @XLr7xY=`4r}s g[)(gV4oH\J~ߪ8H@ [ߥ֐ FJr}?w_Q!6{lǺU4Z@:":wD2!j3dkڪX6@ )N끱(fj?48T BѬ_blm4Q~!m( !+OQ'c(=|kѐcCבڒovP @[5z,nU_pyT)CL*yV/}@c)bʏ\m}@q:\ZSE( PeURi~[kR޽aG>{\~-ҴaxL1:J  P ξZ\1a)Vy%d|igYa>꿧?^@rd  @RB=HVe=b0WؘMS(9V><yJ̱cz,,isi&@ kRi?MXqota[|+oo('%[{bMA@@kK<˶oz);6!?Ie1wB{AҒ  A`!=K#(:KſroB~@R!rÎ"Af7h-T&ؓ똟R @Apܺx,dt67#TO)ODS͟XzZ18BxI  @ xXeg7trljڿwpOI:&@df$PeFuAOǘ13 ~QsbV.'Q @Q-qΫSZ'.xHĸ;c[GÒmXW/u5⾳R @Q[V|"%\}F{6;vH}ݲO0G~i{$  @ jd_ i>$#QGz?}v\zoq5yxZqK@@ȃKeX'e3o&an/-{ߦ)OJ@H$'V |S37y[’-I9O>zU%  @ 9ыRܺ|_,֪> ~1@줪&Julw*1K( .ɵ\3|nhKcrK11<).5wҌ ij)&Q @IAz"' '[XU>"3GB? o/UЧ@'ryG'?K>:8JeJ!,]?rX>`֒( !o8;]/K2ȗ{aa&VJ!N-Q @x<-o K6!}~ n\( ՅM)}~ 5shۤvǴ=`&@ziJ߃LP}r.6Bc>ۋ?ܽq_iA5 @ KKg:%˨wǵZ'i.P[uDZ\c]݅8) 4!p>@_HO2ZֱX %hXzI /#Q @.|v~c6|5NLw$,Ze죹GJ̜(@`OI(>`gRw)URʅ}yC<9  >h=E NZ$mq#`~,%\$#>&  @mԲ>r0*E?('%'orpo<֌[C@ȚxNޔ+g9{BebֳlQZ'w"y9u~}X@ !oi!l崚/vS6ٵֶ g8/v;HtW( N xWn1|g 'y`fsǤ:l`<O@z(<[]9|U9i4M)= x Bb#kI{KH$UhgUg@$ǝ)O>9ƴ^ηS ~қRLV4DISBpR]0WI_ć@ K>9R1a2;q1͑ZǐzDs62 "JM]}p2:}sc= C`gm#j>nS񸑘c/_S&CjƑϧyD7{lvWFw{@H<))H{H:;D5SxaKyӸ"w1D'T=OZܨ._TO&@ $cU]l$#[S&/DO,CWCb(6`mKLm+w=]ʽuУvDT@~רB|[j~C""4 KxxS$w,2RO*Q DA=27}Az@IDAT;S(UiϐO+\gw1I-E㶂N+Î<#eQyC=9\@O殒rhq`#Ta%'^-si6a|pɳQ ?~MzV1` A@aQfޠ"qG$wҗQ䚵7j}I6mHb筳AŘ@ (sf#j4>TT0O,nR:?- opV v7$M 8ڮ|.Ԕ:_@ @iÿk&S ϼL{)W@ 6\).z П%~tD_wJq'?4QYGz*Nb:sXT@R21^ʽ!Q( v{ܣPvz穦wO,fzu@ =ʥPt!۞Ƴzn/_e:ǀt6)N_XE62&}x!D,&?^R9ԏ$"cBy1QH8 3 4'=t/)§qǿAG P:ӵ,˔N: P^ o?7t(_Y6_C L@xjJ#gţe žqm*'mݴ]RCK!MeJĞui=@X)H)HOgb;v:W6y셟v{֭ݶ#ع01QFӠ7mJByʘ tJկm7m$)yϹe蟤nκb,@ҪǤ`8BV'B^"P #OH)ĵn}$٧C`UzMY^~/+~KǓrX N2i聪>]H^u مMd܋Rr_W7ݕ|C]L|B؍~p;_vτrbcժ{'){Еլ c9O#)Çq<8 @ f4ObbV}ܵ)۔~徟{P]ɦD,?璡rw@Vc>y~;"JK$/.t]Nۃ' $J\wH,(qX  ~ ";'018!xvN]!J-s=o߸Rk!|FFOBiP@ĞzIm8BΰLffmqO,fX ̢-?$ȤglL!p~]3S(Xv'3σX_%u{֋4S D F';^4%e>HN4ŝl:=il3 ^8)OěXTES 2#UUA|;Z-Ϻё.ӼTmRqs?EΓ]?ƕX TMxm{Әy~@NH>||;Y\E^{z\k?M\?r!%Om< UڬsiL18ܝ@N)r-kgߞz yNzq2{3 i@/?S06fJj@N\-FLq'c__(}1NeR޳֭_Zc1 P_ƓʦزsbNs(ߗ7n;%wqcsqw  w좟4Sޘ);?ȉmϏc#q~B~ zr%秈9n:'@U~n&u7>Eq-gϬI2%1?'X <HyI}s+T5ﺷx%`'GkRݹAh-K=mpKuQr`bΉR ~@:9?9\.|>db쓊tSqfS ! , }7uJ셊Y}em ~T*gs܇ocr tz.bnOp%@`E7&w rzW!P=|+u^N~8Gs#y@w23~@e~ ;cC>.24ӨsiW9^diHS*|d$ކx8>F@R5!6DutL1H?Sh/b<';~^hf}qf_~X9ܤO`Vpn<̊ȁ/ſ  Г!:r?Y"|Xg')i/$]."W9pe;>C U>9xY*?&\E_c]2<'f,C}NY^Eo-'3F"e1>bmOyVo{ZuDIFgY=%Hwt|U(@$) .<ݚ@pM^CZ1jy]~p,0}9NJ'tiEi~~VXN[bC"'p쟶S xvcAP@xud[.]@ Lk'Oco_I;J2Z+.Ui{ r2_Q H $s,04 !&&V1\6쒻"i4n/KȲ*0`"S P-jAcjk+˚ٱUwX@C`)q9o>C6)9 ~TCɼ(%~Y7/zpe9YIg&\0~pTDr݀nsݙ_ۋ`@ 2n8[sXnW%  % %ڐg]HLY[:}!>)Bυ\Y@C(nj#:dj~ u4#_?`~퓜ЎΘbwO7y?CۿMjgMqكk$A)6FkRZO:zˏToo&(8P.3)gPɖ2eS AlS8_kX?+|HRQj=>q` Ç>>OޒBͽzALvC+]Os=K @` ~B {,bz[8~wX? #,J1jǿ 1{pQ ?zPjW˦-D1P?%=@;d0[}ȝzPߍ'ŗʅ80x4k[Mquw˹Aj?F<6E)v8,@v9LxTOcR Ir u6[ġSPٖm !4/ȻC%.v"ߙt=M#R7~'*I1O*Rr:z102崤1i8xa*eS9R5g*D`9B E\KJriǥP2F̩RyUqz1?nElb[?cJ9'0R<*֘ijX.|sYH,=W(Ju|gs{8h0Ɨ%K܂@`fs/o,\P f!xiĦ3Fi) =]lslFr3ϝ[;tU R;~8GȺ;ZSF1'3wE!-16$ep{rLUkغ %mKʽgABڡw.\F`vmwr; ͵E {Gʇ1KPcAm@ml=%˗:Y=->~v|L1s'; m{k?Aj'WcY~$Q'p\%/˲cbrN6c6oYwCMiLb20eMY{+1udfQU# `cvM8[W58+EfVYž7 VC ~C I_:mw+ĢU߱mge>c9דWUouUmUi_jmԌrc";ÛAf0_εxz*r>xOb{ȑ'0O$7e5|,_1ckt/  Cn/,a.td3X\O;.W9X4 6 f{ugȁXye~Jk27u5}Q"yY 2#PШ38ERj./JmINR?j,@~4/jeT~ɋxG4oȷ5%W>(r?OBM`N붠?f)}6TA`om$_ή|x xM>,0w˶ pn߹%Ya )>nNcΧ@Y<;Oc6AqwWy wS0DdcmE7?. Nu0a]TH O }S.(dw?[|a@#*|'nCìU1vmT>ly BH4 E<ӡ_=]nQ\~ Fvx& %}p4X>v釹0*\x0RT J`7-r҉o ]aA爟JP}"bWEc$.2&Xw0D&ť0 YH\:+wTQF#'U m*=*kK`'i[zwI>  P$EG3U>M1t{1)nkfWIKNw -^>w \Srs-UDzom8>\Nmqlg=5PU,Aj'7RZփW.iV)CO_*8 x`bYxYcʑd|Zı][t) -ʱsyߡzzl* POkG, "@cdS]iv ;&O`cUNn1#ͮΟK&Cbϖ[qb2؜:[: r^ntMJ1\y]W(XEǜ~NwhX@;aߝ=4@I&EշeS/pW ;&O2\7O Di ޱ~wtxhF 8ìy/~MRzY?F̺=mݣ@%%<~78fcQ 0#+A DK uiQߙ,#yd.T n8ϸߙ0WeDP],>xDtɱb<@q;@8DuTiO6).#=%9IOHNA8DFGcfP PGUqh9_=/߭K`cVDX-nh{vc.4 [J1PʴY1* "*.3{۲Qo|TW~սݽBF+;-=%X,fj@/#_y߭M%HDsm87 !V@ ȍV@/^J'CoJ)W0։M mgTOO 2'qO  PeɎ* 0@Hy߭-NItmĺ m4%tP \*b=i7iu[B 򅻌iP{V3KٌQK{y^]`A"֌rh  p6REN ۇwT1md\ 7Jg 1gQ A4r|R #5-¾F"~vc"×˻#͏' @ѶRhjuTo*)D\)1Sډ-7c[wo2"M[}@(~)Cr9'C|+}ql_*Pe8y;6%?erze;X,C~b-%0L{E aO;OaòD :O&ܚN3vJ[~5Nﯪ27}ob!p,mw'ac D7b󔂀/N1wT0Dɨg 6A F:;;܅`Iu;S^ϳFطbBP-!')L"o(P%)}eW^{ $(@γ pQ_@VP߻[X? _)Z"M4@rxK@-+j@B32|.k=P'\ʣ0g/Fo9i@NѶB?aƀMAUQ>ELQ3Bp<3A߯Iu\=lO@KJ:f|S\erzi|,wcb͈fy6IJZ(w7_<"HPU/1UA WuK0ԑӶ0ÂU8QuLsQzUL؁c{f J`gVeުRD>({o1&ar<|DW@;^#XSuH , BJB&0Tf2l@2wXRAl xvc$])z:?.Q#Puכs/zKKu˖*Cd[f;^Ο{JfO(ߺ~T>4Dɏ%{ғ"r):^K=C"u3{@.WE쬩%&UWB`tysSK_rIa {{o*Q zS8>2rIIGǤ 9 D@/^-oV HR {ERfx$n e˽92S7j&.bIJI K~5= $)cV=awJB3/3_)6/ &0JpwFo46.>CA/%'? IKI~Q|S mz;ŅDdS@pE eONV}}F\8TF8m2v2 sRj"qTY@"U~ӕ=z@ _d-qY2M@3> q!@ L⁤n.3\X@th :et B)7+0@i2v|b@y8Onp͆B< @\1? X0roD P0ST_h7MB,J"p6^JbNB&r}sJȁ6@NF vQO_"p mfY*Jub&@=kXl !QZ )J;A@ 6OWg*{"uG7\JcXcm=|[C XNK{ɎzS bmx UDɜ2%Z~ex>Z|@ i>q/sn'rxܜ{n,0zf#6h ml(U Td zqogcBP|P^IYy=9@} 쬏Nq,JO'i޶xcG6vT i_†cۍ {f <(2=Snɮz@ȉ@O K%Ao/X]vked.Vn[3߸>t{;\toATTάse4 Fên3Fz*\566=}YCXGOj=zQ7 &l(@0uvSpz:j  :>m>1 eÇ6."!I6C//TsPD`zOɯq3<7i͹/j,iH4'2P-_{d[g-NBB@ i 'vˠd t~YX) L3, D(} M1@H.1&ayyƖ'1M7Bh{u.BP|B.Y-Y@S_ ;!IK5>Yl`\ ̧_? AS.?W{yyq^bun?M=x-p!c1WX i ~ڢ-A@ 'b@YoM!Y"46 iN^v6̅Lkb-A@ȉrvM}q~GX1aCsFH]w|2'[uŤvɟ3|r@v|L=;cלW74h{6izzlcl/}K U;bY.q\^4 ;2~6Cv{66< Nyk?Hߗvx T]/,=i@ gk3S<9Cu%fQdf0]<'I?+ (v[y3[qȕ@`kc{a#@(,h{lF8 |Qa_F ˄O x6Cw# %56ًS%06wj7ָij_g ?C [ct2J<|xM˫o'Y`Nq!< 髅7 :8l ح6:zG!5!s!< cS@XAwiLs6A~37H4ʓ-|}Yr}@|\gq}\D_{ܟ,&b= >ϵJk\-ދx{lcCtN 0qNHtv>"BK,.>~I#@wB&RRDAQĊ`/H/"M"{"5PHOf-27s̝[N廟ge=s^}&sלեMne4@ &0rXL s;qy%0_>[Ie/Kv+mN7k{M(VnUDu ZW4宓-ɷAj`=I+J믓 q:3s5yS@g *k nV:)9 &m7uaަ*ɞ|nPa@?2vt^f<I/:٫;`F!1 سcr+#v ݨQ`pgebfakjI@-\BrxG>x.ph @L(!1%\V#tD?@;k׾8]Qicoi[^d|::ON+!D'SĹ)e,0wd2#2 o^`#Umv&Ldi~y_3^̡G!S9V]= @d(#k<h 87BH"h̏W_v=1DŽ#vD,Ec?4!}tX@oQ> @$]<=Cjy&0N-.0E qeXu* VٮiS$@!`7X\_/okR_@ <ҶcFzOq&@>hQoVX2V1_Q)dv'eN6] `?\4@ 6}@dT>5vv\Ņ Z2 OhNf  @Oy%IуbOԆVEo7*5>s=n14@ 6pLU6ȡۿO2,\.}3I>oWb4Ѿz|R2hEon1 iu$I_PvWk괪a" a%4.SX64Ic%M7F3?4bT22Hiɚ⛉ s2Fv }tȴ)L&c/dnDIhVso:b- Wͫ};V4`+P",Y Bƞ X@H,˔o˶#S8]}Fۢe,ze]%KA:_?)Z3]&X; ऀݲ=ˮSfj֜dFeL4Rw #.Jg+&5>fVS!1Ve۰Z*HeGdN0ܤ -)AjIrt ra{N.t>4.WLKW.kc:VHoEPʋ䢷_G_氍(6Qe7"-QdZVVK @{FYp4f*wgW>rw:b-d)٧(ѱ$K @' .NC= U{~OucD7IU1]TU JX狦ݡL98~an2!4bKa7%⇊b,d͋5bVt'],9=LN&m<ڳa.8C1Qq E*ziծ =χ`=^hpYC|춯ƒl y%I6!s[$%(SX[Jqb<͊[4 VX #_U1UY2dLyRQ/@׶>4L!XnS ]+ZNm SK(Jzá饉~Բ#5б\˾mn{-32 ʩƧ_=1I̝W Rxn(/bJ۩*klꏎy{o!@Vfͥ$A[r_@鄜%wC+6VN񾢞vf^B7Bf[ !b 9qZY "&(z;u|ԤdRKkzi'"[o0k\)M;YsmZ6<12\_}O6rH S@ |z᧹0C E P5Iڧ* $)z jO{Xnwb'iUFAKFG]PeuPj.@o}kP mC18E8|)[6I,jEo4gk\nSqX/?v,f 8E/ @0XJԞ(N P}y^ cV)霧׹kWEsX ƆMK,/)ԜL区 {;}TgOj#vY&|PȬ/n33" T>Sw_voLCࣹ:Y⇑_Yܡ._RDqbݭl=E-kd(Nv ! 14˻$kLl[#ZcyOT&^h GdzOJ- O%@2-,_${&nH}SODiwG lH$e4yֻԭ6z!јb* `eiOԎ$@HaKr^i Mng. ~ h].:) @T[(dјH戉ɸ-/JߵVrM~`&n&i,ie7l<mtՖ8Z}zXmmhB.d8Nt&U[LE:L"+-2Hf917?ZxXZIvk5OK2eo>mB:K_@vyz cW>㓻UȜ;LGӝBNJ_ULS *G<]ߤ=ܦCmɅ:r9FE̵>EOcة}:Pu|¾*}xD)`x n\.Ԗ>~յ3@ےANN5$J!cGc.nH &(N@VӜkU׷G'K:89_XR.>LO.3)yePN-`Һ \uS@h֎$G#ɓ43Xgr2uKݚ֚N,nlpJ4N(:Z<]; IVTe m;Mspז-KMJ^T:<#)1b 2+IeyÜU|Y ీnQxz@g%WN[2jVk2J-6Gn PZmgˇ*X&hI&OjA*tXUNTسch 2?HW @sP7\/sCB@`U ~^* @h 3NGo4 @2>\p4~z&8 @@ NƕK@ h R"#@i^+xI]bD!k!F'ջ>w!G"X>9,A&E9#^ \R +t ճfFb @ ~*>n+zYt#n`*c!aJ{IC,awG|,d[Y]ꓙD/0JV̄Đ$7@o %p@$x̑8 The>jLDC0"бh&fV @#έ+|EbneLVV݅ PȰ  T ^A)M JXXB&%5WBf? x̯wxs<|  O w+r.LEJK^uR PUBf)~ת=n`d*Xs?ë@ @}2+ܗG%I" Pi @T2G5*'{Y2' @ {ю.#@>2v\zo@vП?fh# P|V/!_Ԁ, B?"c! Pݨpf٘@@LȣKn Э(|Lw(7M@iN՜L73t&#A VzA8u> u#2u1;!zie]YtmLA"0ʴ&}ZB"YF+mkI"ynTF3" pDfN8,5 ќvEa@; p9P.*xf@b8"C!hL`-b;&5v]y{_oSܤTjB-x@_ڈ @j .9fAV,g)QL--rbޝ(~A @k7|^G*>'*E7sZYʪ0N *.y#@K;S)di4E4V:xXN*iej^F@ Pj@#) z~44`=+[Hwh  WQԾ?0g+)^VȲ}G+,n 2sZ#G@H~"ǜm#P.ёyݒn|Qt4nGCO`~}{9w G:] Л fTt?դiT#P[W6s!tv l$)ҺQЭ={g=5*rhL㴲.LEzL> ,U<(1c\^вp984^0کe4@b(d 3FeK]_52N-[Sڡ@Zoy PLX̊+P|Ѿt_At˥#2LZnLChL B[6ovGB{s W6϶hKGdC>M'@b^-W4/`k]ءUedlpvO䝼2."9ݻt:7*հ0v eвp Gco&]u2S@YpX`yo]c[m"pgI'ܮl *#Akdf\hq \Xk{(|+bKL!B!cw<|^>w# ~TNSi&`E5Ky݌ Vf : u @2Fz>,S*쫯m:>oW 㿵1v<,,6!,$.Sؑ;"swm}pqV'Um_;^GytXٟ܉gXGdp!UL3vl$!4!@!"_'"fr3lh }DƮU ܨ1<2k! PȬ#>sٜY3쮵Ib&k/nVpZkqrGd ͍L7Dž^!Sz=9ynfDx%Յ7+B+bLמyCXBf?/|[@@ሌimkB Sv-nOԦo*nlB`vϮ$N @Yأe9+o;>[kEZ.j#* > Ze of*Ec4-`7v® gMϡBnG+wz*;Ǚ `}tXM 5ܣg~ܴ+YS8]INf  @| ^MZ8i ~xZ1&:#kR>[Qo4  +xrU [FI>"Na]1k3>:F @ {g߄S[XM9VQPܯܷg߫s2\?vL iUg[Ɖ ! BQk(!*e"EZ,=.! ZD=pE *^w,ﯠE*p -5wZ0z|ڪ]xw27'(}@k+bSwrߴzZLc?_*pشv|]`1D-oeוxTUp Y?_g77Sгl<nBӮa  @waEK9G֜d]b]v+bmy^y2^ri  ةUm=oↁ-g `]Elsڭʿ!iXc<[? @v6~~Z;l=մv T(cWX*ڼwB׷[ @'.R/\Wbu'FN#`Eq?7Xi`G!'p l)졋Ӣ/sil~(2E;@ㅰ;ϸ,;y" +B}W3ubm6u5i 6A6L?R_c@iB54+Q:ncvI -iIǚ+ZrtMr̄ Pp-3ONvT돊]1^Hm9o8]ag+_5 )h ЫgdỎf^T+@T(y{RX͊S!Jc_4Zv-1z@̪꬝HL/?W  ՗87eG%쏜vm +_VԆ)>QG<)ms%KM BTꗩ,}Fiح=i n E)#W6/8;"2jۿ xi~^hW(hyvĭ4~!ΪefA(\'w Eh1Y_V?yOa W jG|5;Zbũ݄Pd;ݻ~YQby'0[]Yٿf*dMf;W+ʇT@$ (vhQ*`5-|;g-B~ELtM[!8.`㯺R{;b;^TaEhZm*o*(bdY?G}Cv ݸf?]D%0]ٞ$I@sOwx'GS;d ^'d7`qol Q's.k+@#y"@mCOjHٷE1]l(2%I@ LJ0S#+xU=?4 4{-o[F^!a@Z`Iޮ@;dݚ@fl5RTrZY@%v* xO*ߛ-6[pZYPۃ;@O~~i6 K_Oq (dҵ~X{#U6@m6@lvc{)ފ-ymLBfUmr6RVВD*`7i@^iC(N2Aj2r2@ /3 @ ,; sbW+aF6y4SG=ᆆ }:+vf VBnG9۬8gZ@~Nƿ1 @k%"ց;cnŃ-=L_o!ie;]oo;@G/"P.0CoX_1F  4 FX`nqtF.Bk)VYAiZBf6-N+ k<hD]-n@C t{n}N=Ys[BSJe;[Mn!*0A#3v RR)6UpGÜ)d>rix 3 ;݌@(v=VpV!NU Nk- @Nk;V;;e4s!}a̢+x=t@ KfbY|cv ]OCiZO-㴲a|\o_;@ ]-WpB^x phS$_t1r v[@" IO]+1]yivcd@: vߧs5zDݕI:^˧; @wVW.WGf:DhDBvtZuX @65۶\d"`G`M7fVC/sb0ѡ+ ~ QwRس8݊A^-vRJ62cұg@hFj7w}sZ]/42@C@;g3ͬe"0GxBAC :;t* i ׊RWfڇXZAC zE3?P-k^ @[i$~7((!@ODީY>}6@@nƊ+ 쏫+Dޕ !( <% _@P`` :/hb,?b2 i u*Vt0LfhP5yÀ;~԰0  @vm^Q { FfYu1+ i ؙWS9\ߟ*W@ZCQv0v$AH]`u ~Oa`b+ YckMz8 i Qǎ>}vyWcW.~ $Kǧ )@XL+xC}_d]8UJCO->LU ,/mN'[Ba!! "JfŮ1O(P.6GxH@{LW8"P^|F}֑~Ѝ ϝ @CaNž"fC~Ja!gk^&]  Lyg{R^N/6jŽL/)ƕzm@3#2=ݵ.5C4@X `쳂ԊiȻ٭( ; I (2u@M_Si  P`jREVz=@ѿk鵽S*Gkf"E84b4 y1 /0K)\4@ 3kY$^  8*P*dqEu6v@@@wR!VF5ǣQeK  x&`[1cו.,ԻkpP{ @@"fqEL<1B@@9+d6':^ @@\BW L@@pN ;C/y  . r9M۳'Ӄi   ਀6y'w@@\ASתw6qZYl@@`I帲bip==K7&J̓Z^M+)dBEr@@;obc)kV\8W1^nͮ=v@@"XF98]qYii3t;+0T drʿʹ^SG@[n ;g ZrY  i  ,%;2Aؗ-YB#(-@Ac@@`P&Pu$m{N EF}:N/fG@C.ַ[y|i/+hu \{ {[i  ~ l_k]{OAC.fri>X" +~µO-Ӧcx}Oql@@ '_29Vd횓K02k\  t yo•ϟcVυ jܴٳFfC@G`Ż>7;VÚ7A*j{s:l@@}ϨY>2ϮNSW"1w@hV`>2m|8Z@߲/ Ϗ@@F) )]r,_kiWoY1  @(>Ry3~u><[F5fw} |@pWp3gZݡȿgݝZ64UC @@ (VMtæ +dcOo=@@Po~N,,fJnU4@@)~|{]!cnT   vszVn[xC۫i]zvx|:  h%xϒEk=i%sq)>i@@@Tjm̔o\o!LZt׏I@@C]la!p^ãWGc[->]$zz *O#vuB@@P("m?ʀT-g<  @U5UE ; {2/*\4pUM@@P.u5C]מXyAŞA  #_+)|\gspr  -QLQY[K2Lv=^W߇gê@@ lI(B(*nVWR4"`XU Ie@@XFKM i|mdg5$B wnT42E-s^ @@4he_SLS/ SQ<>.! d+Vχo vX"Y`%_aB@T {τLGW]di^@@ M>K1<9(ͽum.RRL)b@C@2~^|mE*h ,mO*6R@@F|TZB>IXc3+h+,Zw4@@t.S?>L0Q !xGNh\[AC@HWqb"nkRnἑD6/+٩gj v] @@ ]h[ր4{Ɗ vn已¦[?QDAC@@:м/)(`7]q$Y@@N((`7g*~]@@jXG^)CWD@\`W|EL14@@E` }Y .?   @OMLq  = V/ -@@ˊ7|-JfB!  PM +(\7qEAC@@*0- ǫ4Nvs  t_Sp ;;o@@@@)Pp;E  e!ٞcO|*3Hq  eŊ  Ԙ!  *VGA➁=GAC@@ z8U1AA  V"@1CA4   RJd  nqG2!@@XDi.^|Gq  @tÔvzG_0f4@@XWxמ \e@(L`bsf4ZsSL$@!S+  !0T/HzaWRI/*8.~ @@ f+XQJaP 0S++ ƛl@U`_[bVpE[ {(- @4@@c~w5,Ezoߣ%⊸Ҏ#[ 8ƙ,@Q`PQ^ibZv1V|7ESȄ;d @(CfEKy,J䑪]TʜqnH  璕Ŋ^]WAC'Y(_7 G@pSNS6. +Z9-4Z \cG@E`iu`k)ޗtյvW2Zd2 8" }XUpY.m8f+?S̉)d@@fŎXRO ,j_QLr#} Lj" P@uv_*XJG\1.VX!CC a'@@rnŊ)h!0K?9 ;2 +`ža.\N&[Ao@R`%܊RᲩ^sMK⬻QW4 _B&1&C@8UVlYIA |@qbGP&@HYkK-YmVCc2ŏ=@@^e6Rbszԑ!D/@*(p)=t);sŽKB..fF@ sގXѲmJC Jnl1+# " v'1V!Ђ.*(#(dr'g  ݵ+xXQAC t('@!5[BO&f,-u8b k"6 (d2e Q P얝vN!T%c%OPV@说6UXbasd!Т8[A $L.l@ N+.vw dpI)V-} 2 (d2'f  練N#@CَIB {  _˩V}z@nkKg(ml2 2 ^"D)`侮 u4^~}{ Ll@-%Qz[]78)zuV'{GnIRN]b7 &pf6/IB&'h6 َXbyB!P5)cfE 7Sύ !d,`=촱2G DJrůτ 9#@!X  \w{l":o S4q~  @Y®}!@ch(5 B8 2 @mvʘ-VX .S\xUnPȸ1@R.Wa& ~_ @ok9;r~Eb~IB~mؿ=V "+@8ZU- A P5$x%`HQa~Q 4.0Eޠv| `(dZC[쁔VicK(h и+Z vX@2Q 3I" TSS@q'?㿍%[B Ա+QP@;7b%@!p  Pmnlŋ]2BAC^b713[ K!LcKf @(y iƥT<:X(dnERBk:Ba׽Lm&*[Î|Wd@s24 *JsfL+) XrTOi((dvFjX\sQ+`y)fDxXq?m RIU  T>vd;u̾{&`׶(xKbB!LS`3u]oGbh лb׷Xܩ!@29 @a%շ)~5\"ߥŊ{OC(d @g @}]_P1!F5MKa}}YAC(d$yQr&A7+TQ}K"L,#M m9@EŎ  2ڊ+^, <D@V2+Q,,@-J)}{ۃACG G>#i. 1 VR^s;rJB&$T`8׾D_+Vp_b P8|R~I4Y(/ehŮw!@$2 4i"@0CS лLŽ<+ "tISNRǖt^"V.ҟ_jXB ud BF|U2YcyBaGZJg= P.@!Sk@ (6sKT&kmv7)bT@ x @#;e;A`-)x@q # &!A P9$9 6NQXdcq ZS Z$d Pľ?+`)dQwaGY.//Z=kY@  xƚL@9Z(ř[K#PY}.ҧ! @!B$`Ob  FZ +ZJ=s4@:(dcvJ`/ecFQeMi V*Z׊rփ.@!@ PM`GMbjdUԴìxbU%@!$AQ(H 7JGYJff: @62ٸVK`u,4J3 T/}  Pgϖ@xT /;`žr# Pt'tY;Ba/r֣}׊R^3\h Px0HtRYkbT\ `yb|!@_(d|9 3`~س;=Ŋڿ @@2 & @Ua=ũU`(+XJaIG#Pķ@k+: :_.`=Å LdND"  ,/*(`1S @@j^󽢠npSȄ@C@@֏<2%*@@@F4] k904@@C`w"&?>Ma!  @v৊VEL>N[TAC@@:*(`1'(h   Ѐ̻ |     TsJOsT@@@Ae} donpX @@71LJY4@@s1̒;   @3|)(`3k.Q!  @+j1< ͛'G@@vEL6pE @@R1_AL@1DAC@@kW*(`10[;]  ) zQPĤo`m8@@hD__WPĤkLQU@@@ E 4@@HY;Z=Ä"&=Z@@@@F   d 0R봇0RĤc0]vdˊC  d 9IAU\^AC@@vz)(b7x^hX-   s1id+(h   7nL\cFʪ@@0{iE!  @1̒ F&  Y , ܯi_[5b   @`}yAAӘ%"  @h#o)(b7'!  @NcScECr'6  {LGb3x_f'(n4@@Q m]WXwbljM!  @ڢHL[_@@@ gӴ= b|   cm"vA&@@@@}*(bj3b~!@@(B6z"6d5b   @`\`_ƿ   P"XEL2bQ @@ ;lݪ)p4   ;1؃@n4@@(X1<"n,  .Pt_Xa7CuE?>   @  T7SVcGA@@wd)(b| c*z  &0Pq"rB!  ]q"]@@@X G_.VPT]&K/ _@@pM\u"-y @@8S/)b: .-7Ag/ͭ@@@WeiQ_?+6F@@URȜ^ڬ @@|XDp@@VpF4@@@5B"P1@@J}:+Ō!:9"   سeQ]LW4@@@&4CMk)3!  e.EŌf @@hH`"bfsJCd!@@@4ͮYɪE^v  4%`}4'= #  홿x[hAӪe w$ @@M3Uس^z+jfh[*VP@@hD9#=wfꊥCV|xKb    JwA3IENDB`catch-1.12.1/catch-icon-tiny.png000066400000000000000000000061161325474075300163730ustar00rootroot00000000000000PNG  IHDRg5 IDATxyT? ʡP";μDx`(5&^'D@j @F") !QATT<"TEVٙ켙~3[c7_w~5G#1@PFPta5`Pm^C` 0 t7l;p)Dq1 n`P7y! @84xC(mf(_ LK{8&: ؐg(m+f9ʁ_`$k0{@#@iX^l\O-e0,^+E0{,fY] v5OmJ<Q@=0X)vG¹` _l`EGf H(_fƣ#^v{2' xΣ#+(:zx:`oz!a=a_<X+lǛ0pG`4BZ@i27d.Jas<0|m0`0FjA{"[0=LLꁭ`둭r VB\3K

'`69 @*[6/o0'n}mp~ぇ+7~M`Ns #+uj [l93[Fd >)Y>xF?&*7l~Vh0]-r&dh$?73TNf'je;, f3m:fu& qt[uSٿKr{5 qQƕvׄxZ~0S t1XT" OK7 5w x>=V-`\tkvK¹"V) fnp^t~+,w%Ӝ&XD9AIa0Ky=Zgm"vi)ŒEHI-~M̞ Pox U7]P-NA0`QYEX9 L57[&JT9ԧ!,R=GmN}}ޕ)@/GE=Ruz}-j~?s^}9>F.oQ3=)_GTs5f,ݔN;rqk{7˨OeW:j9+Am#cCr S*PCը}֯7P˪hڴ8:͕Ȟܺ@ʡ3ǥjy~o&3,aq\9Ϛ~k;Ul\LPKetK<6{/qy`™-ȵc/-AxUT*Uv;&<6# z m{tG1UlO9o6C?@"#`u5x)yJW%LL}R!I{$^M7dz]@ʗ6ho <?>n1/r3C)5Z9/j9+WCBe>r5; לpX"@J 77S59.D$Ia%"wS=:Sy\S\QUW* 3%ZE0n@xeUp("t5>jTa*0"@ X--!Pଶ-Dw\F/SV5% SV_tx^tNB.YAwL!01:'gyEjOdw,g7>$϶_״ ]m9py-LBȾ !|BYgvܱhۖ2윫.=烎wU ,y]W̡H]̞ ѾP\䧶]Z7|\~k]PK1:q ^H|}EequGItKbد8"YG(ѧO8"0JF#yos9|p:\P . aa4o IsM)j%>X"B!D6ٛd_➒dq8pFU3g4eBl1{ vIJB!De5) <FyNMS!r.!V (r*yB ehBWXv[,iZeݨ bB ; !p0/CFTLU}_Lw+ke#ʙ <)(BT3aiĦV!Bsy=$4x1#FUC9l\귫1/BRmcY qf Oap017h  K`^/v6zD7Lڪ/v'L}YA10+Ws~ Lxh1$ !uNġk a\m}a9Ig NlEv4aGðbή`=B2h PC @F GOބ__D,6F#(םՅ L@ ê ?N!;ǀ` ܨZX_!D΄ם da}g=հK1=c7]̍Օw^|%xGLgڬ}ZFUSze;O)J=sdMXҤ @7Vk>pa!D0kUNXƛ_I og/i$_za^riRze$ߠ/v =$O~?-GȨŘBV#E5c^O )>&KI.h?4-/HVQٜ!~/90( 2ŎuKqlVLeu&zqdP ΄x\VwcU7L`uB܇k8.7OE/Ȇ"X989%GլȘz=;0"$K`bu(;KD y G]*yX/]{_d:JW15;wgdL&dCxy~F| \%Ez^T=O/ey?ULtQT^kLFd=;`ݾ{Ɋv%{#@^ʠ3P&t"ARvΈ}Mg м&XK*ऄ{w`xqc)1vZY20#!|K>ܧ+4dvZ79^lO\~c rnBkͽR]Z};< :>:SFOvX}Ny&n;y^QVbYa&o/B=}_aTJyτ+ky8ȃ%9Z|q jkWF@VqVobBC4EՍ"쬨. Xڽ 4XZkVvj JO8AUp׺AB0FZVB, עo!Oǧ0ӄl^q6w9VR&a :iB,:UFф=Sե J2 pﰀ%9Jzj "qO*Y(pǵ}=xMVγ<8x1VhBkFD=ob!Cݙo/y0jNBWgQAj QWOzcn2T,yv5fPPRжd,<#U`zZWs,}yh~ шƪ",Ghc{vN;#1?cG&-{0 8<!bE`38߃&Z?W >5:hkͧgZBr73'qQ*kaS9,FHCQ$STTKdz1l{uWكp0%b `\O7j3cE!6uXUu3t~}RjMc0A8۱Cs;}Scs9X[Hs@uXךx3qțҾ6㧰ǁgK8cw a:\#DS~i-M"_9i| il VNy.l&gQ{|LQ,<a"gr㓕p "s{/zYת>9gUnBTEH8G.nOk#DŽ\J([ qH[<xxR0VAo`Z(fHugh<ĎOwhϛ] `i102UuKXM鄟js5ԝboK dEL2N[7`pg`GC,W?>CUc=3.+" O2Чь)ӄb m_$y.Ƕe!o30N~UH[`eG^P6؊){`(flGTxb-`~ѺODKS1Ƭ5M)Ȫ/U̶X;ʪjK9]=i^3+Ըjcˠ99p_~kqg+ܒq t.X~֏aNI eu,MI2޾s9 Jou otͮxMk1?6gbN{iÎW;FWmĎKFðm([9X@\Dbƫ !w+GQ})Dkhm>zaGi%p=&NäxNb.޴$DE%2 (o}th˯=x\f.يeʦcYkMi{1~W/VF)r҇L7PG5y**0 K<4Y}|td""Ŏ&OLS~+?~nqs55z!fuϔ>"Wѳ,p~\3*[ pp & uUjHqļIS)uݐ;΃bs']=&v;y}Yak |k==U_Z#cJ@Tut {{F}y_VHzg$+r#7=h3# -?F[z{4>&B]ȞFa wMuuz"ݰ,Ӥc7f-s6휝p\7W^uwFE\>&ҽ5ψqX<Պv,,'x^K$Y,:c)hŽ Wg3: `Lyy,!i؜w78Wmcuh] KvY&;:^ ӈ*U7𩌡 kNQ cW;3y|t` y_{l_Ls'n[,ᅒuCwX]+:-dԄiO)a2^?|בXa#pCBϲD)Eњ:~z57 E-W  e*(w0]d[@/٩q|&=6ȱvAޓ\gޛ3=ܡwdlUecBtQ*Wz?fpo8&ޞ.K;g nU uJi劚=󰌪Rx ImrfbG~_bR8oDɻ5ਟC-O2‹˶>wǎC$nBIx*`!.IX\Q<`23};X|Ilf р~dJ0Qj*^JcLyjہ55"i,vD{5vdvE\l{d=Il󥢍tߞ@ڌk_a>NcZ .o-[ĔC`gy9><O36KOr*}^I[I| E,GƖ 4e*c 7b*kbB=Ggpr>S88Iݦq~tJKHlQN)ݏl+fg +RUp]TA.1NW:&|"orY4K_wse/i$[!czhq)Eu<{̩#ؼ6m>zX ?|m=} 铮;yK4-% ࿨s=c(EW$팿,,s)J33 ̱{fdT|6FfYlވ4{FT5)ʯ=.)|CvaǾJRKkYNqXޘ|Q4%O\o; d/;U ེ6G{;՝Y ?Qg|+&9+6.^j{{$S)=٭߆dMO-.DRKеEUr[T4Y ?DE` + v>{xϋLRd7o2ýP_߬rg\{fd8;3܍ s)1ܞ1qSrەpvM^NWk ̘} U=]`b])Ke6^{ dILXK\ ŏYwh?k1e_OhGa՟ Pj~1X(]us Faxq0RM6ƽҽ-{QznFaGiggH w6`"[va q>iŕ#΁}𜞝hƝR&E brM-WP` ԖD: N gQr<>+|,@};9up˿T+G/r܌[ 3 dkuiJ M}<ϓS qkt3mVGǟfB0K<īs8ꢵ-n8Ul(pl/,a(ֺʃ MWznRe?HO&D,Y[@Z:`aJ>('XIO36Vv=1ىYob7y-pw<;]5XH^C-V"]pT e`IN05kjRR4kMŸp"uE*3pcw\9wVڕ1+Mjq kyOO7'qx?X֌}1!8t͚?A sdFk?7y#>t)wKI0"\>N9a,<&_v2 luK~^ٕu~[(ɿ"/S)~g@"6S}̌y=Dz{ td`pK'S`VKQ,q$UdhfvNp썻28~Z3p?+)BĥFK"cKy;l߃ \L7.C'Vxq!lMH5ԴԊXhyRtv01ϗQX r5|ĭdC>"R2"}"A\^ƟwF<ϰdRXbǰ6I X}XK_%n3*^,"CQaP\`>+iHqOm3 loM[ߙk{p= wozxsr~J  j p8lr{{% ># ςmZX:ߌվB:,gOY`}7 ~U<1AVmkOk[zyX-= .opM ]?e0j˘mT٥~ЧUK^n5 Ӌ,PC {:–xޞ·M;@}d` nUtPC6AE6z(n*,A@A =;"{Jr3N9w4}yJZ :[ͽܞ.kXQ(P5Tܸd pXn&}VߺQd>06YWZcfNʙpUT,,MV#XO\u ,q)-hjߤ'>$QA3p%[" HcK$-OV70bPÂkn5 Bf^ǟ-YXzcX,CV)_Mj̎?vhma&8`#/+ZLbw DO/b D2:)yI<*Ŗ_ VW 󮜈Ź.[d/id d5,>hyG?'9/fcZN(`81c#,M-I/H{``܇m@ |3O|E়|Q U lGG]BDmjХrNgc//En7Rz*vR74xolMie%e˙TۚXϵ7I?wZtue`n(/jcu ٔt4 ~@E6*k_`@1ɽ";c-}pKab< !+V?wZ[4ou4x= ܖ~M6Y9·|oZ5ةg]<;~;+-%'lg Ɏh` VX5QהPaJMy ;Ξ1o@|*DOFXbzG`[ϿE2WO෦|.rt-%N}5 /t2^*Ed 8v5Vv)gQ'1 2g-Xn[`~+Mb2ϛ2@?KOp$N#g'<¸XbY!>y|V4#ZoSfF #ylL?Sg(jTS4"bHח6ď<5i|5eek%eUk-e3^ljg`5pv6Av\ {qxp1vu؝5c9\T*n HF ZIgzp ]}x?'Fq S[<"c)G/X Ϙh=Aoť^뀕I=(ҧ-V tS;`y֋Ѹ;n}VⳜ@oϿeEƜo| 1g*&M$OT*wIoXjHNmuy`qk~O05ҠAE@MߘۅևSc|rhf2U6 ي]Yt=;t6gh~p,;|G&etqOq[}5Bǂ5c|X37oxFaÐVW`7~Ճ5`@e#i"&5`P_^w Fõw1WϠyҬ#uאFXnIT+NO'  'ƂTL:.aA<\Z,q[?q$|eUV)џ[(~W >Qc8֮n^QR>V88\ ر℅ 4^.u\{MvTҭts H:1.cS}*VP_MxSf} dIeZ>g,iX ] XU̹XPc33zq$s p/f8+˹Z~wr5uM,+L"5t@6s{3] RNEy:DWci>Fp2ϫ&|SYx[c`mLsږx4s<|G-b<^ZwT(-8{^4| {j76m)]r^l@K|k332N'>ck_9.nTWdXTCS-ߗi 9s1胥g=#x4oywx.U nt 1!6rllJ? q錉0+w?Oz+ Sn#`vy4V}n9w"=J5.hQ/GWC4yt>ku~b,?+O:[+ز<='P^,3q5exN=A'TjߙedC< 1Wb gzK:=H p;~~0>z24zYλx>cpٶX+#m^ޫs;8@U1`oRߑ rXɊ)QKMc0u0-кwΛWyO(]9֋<ɾFݡt^_tŃ;.8u/V;PyG> ᧄ9z =<2WbGehMϱ>b唦%ЗmmܯJwcU&c ~ _ qJڀ|࿑wiuϢi.Z4ǎ^Hhlz\qj@ X wV_OTd” AIz ;v) }&c9&ʌJ]}O:qwQܔ#X;q?Y1*VHΓP +_I lYtpTtDr+8t^@cjY!AO\9UbI":&@{r'< ^ l\pjg{Kuƭ")`E]?"Y3t᷐t9W pm‹An$~v[)^%kē&^0:رq~ {q/YŲ~$B]cǚm)a~6K xAXЅH^ZDdH.`>{?}4(zD)SJ 0kǃ{lUs +X|Z)C?,P6nLLX5sa4BY')/I *Βg{V_ јnX4v1K j=L4FO?,XZ dCxegӵt=OŽpP{#P{~w8Fe . ^(T1)-]vY%'Ǿ>^ װVbۓBK] pjo;?mX6ű<ׇ׋%gzjEz%G[s5UdX}%|et,z{ˌl~8Cه!22TL6dPJ?Gz%Ǧ&\x<,LR<8zfc]O#9=+_i? G20ӜoͬHV%㯄*#=M`%|Nؙ=Wc+>+7 xGZt\qKeXI0yˍRK2 e(gJo?C7VP6/ճ\XX89< f]Ⱥ3ISGs"V'݁K3͚I6mj3 VƎF|N3ԭ;pWVOGGU;^=<{mEK0B窘0E]h^yL@S0m{kl,t͍1aO+a`1a αfUtg~Hc? 02/#c KG,/v: d]!rO(/v-2 њ:52DX,Y!a'-G͐"cj|dyQ_`Gso`&h7%ؑǐi2+OLhI\PRDG3 5O](/j Pie p!H=>Lx[2JC(CY2B!R G ;LB4k·aKK[ጧ̕v7P|֌W ! m"jYV,Dgs,+-]泱iX,4;! _smu(X$*#K!(L'#!B cWD0B,vJ' !ȩ!K}Gj#3LzU8~)_) !ȡ"RU*p|hy|^Bф#W$suR:Gc<7" R] (.y->Q!ǒXPW^u2ٹO])QQ*/p*p~Db) Z!ȗ|0{'2_b1UB! ,}"jh{<^dLR!2DZa'keX7fB!d` 2&l4sxM`,РB!d`eU3FmB1&}B!4cԟUN!BTa:OiUB!!+dT%4B!tꁓ̻ ˰?!B\:T 1@/ B!B-p"0%a ,X]B!'lXS !"oiF%eX$J!yp)V8 jp4Y]/B<,tB<]!ye r!BY WÀB!3k0>ڨ˅Bgz6. B !B7WCB!äBVuB!oV3?"!BTb1Q! B!&

<test-spec> ...
Test cases, wildcarded test cases, tags and tag expressions are all passed directly as arguments. Tags are distinguished by being enclosed in square brackets. If no test specs are supplied then all test cases, except "hidden" tests, are run. A test is hidden by giving it any tag starting with (or just) a period (```.```) - or, in the deprecated case, tagged ```[hide]``` or given name starting with `'./'`. To specify hidden tests from the command line ```[.]``` or ```[hide]``` can be used *regardless of how they were declared*. Specs must be enclosed in quotes if they contain spaces. If they do not contain spaces the quotes are optional. Wildcards consist of the `*` character at the beginning and/or end of test case names and can substitute for any number of any characters (including none). 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. Inclusions and exclusions are evaluated in left-to-right order. Test case examples:
thisTestOnly            Matches the test case called, 'thisTestOnly'
"this test only"        Matches the test case called, 'this test only'
these*                  Matches all cases starting with 'these'
exclude:notThis         Matches all tests except, 'notThis'
~notThis                Matches all tests except, 'notThis'
~*private*              Matches all tests except those that contain 'private'
a* ~ab* abc             Matches all tests that start with 'a', except those that
                        start with 'ab', except 'abc', which is included
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.:
[one][two],[three]
This matches all tests tagged `[one]` and `[two]`, as well as all tests tagged `[three]` Test names containing special characters, such as `,` or `[` can specify them on the command line using `\`. `\` also escapes itself. ## Choosing a reporter to use
-r, --reporter <reporter>
A reporter is an object that formats and structures the output of running tests, and potentially summarises the results. By default a console reporter is used that writes, IDE friendly, textual output. Catch comes bundled with some alternative reporters, but more can be added in client code.
The bundled reporters are:
-r console
-r compact
-r xml
-r junit
The JUnit reporter is an xml format that follows the structure of the JUnit XML Report ANT task, as consumed by a number of third-party tools, including Continuous Integration servers such as Hudson. If not otherwise needed, the standard XML reporter is preferred as this is a streaming reporter, whereas the Junit reporter needs to hold all its results until the end so it can write the overall results into attributes of the root node. ## Breaking into the debugger
-b, --break
In some IDEs (currently XCode and Visual Studio) it is possible for Catch to break into the debugger on a test failure. This can be very helpful during debug sessions - especially when there is more than one path through a particular test. ## Showing results for successful tests
-s, --success
Usually you only want to see reporting for failed tests. Sometimes it's useful to see *all* the output (especially when you don't trust that that test you just added worked first time!). To see successful, as well as failing, test results just pass this option. Note that each reporter may treat this option differently. The Junit reporter, for example, logs all results regardless. ## Aborting after a certain number of failures
-a, --abort
-x, --abortx [<failure threshold>]
If a ```REQUIRE``` assertion fails the test case aborts, but subsequent test cases are still run. If a ```CHECK``` assertion fails even the current test case is not aborted. Sometimes this results in a flood of failure messages and you'd rather just see the first few. Specifying ```-a``` or ```--abort``` on its own will abort the whole test run on the first failed assertion of any kind. Use ```-x``` or ```--abortx``` followed by a number to abort after that number of assertion failures. ## Listing available tests, tags or reporters
-l, --list-tests
-t, --list-tags
--list-reporters
```-l``` or ```--list-tests``` will list all registered tests, along with any tags. If one or more test-specs have been supplied too then only the matching tests will be listed. ```-t``` or ```--list-tags``` lists all available tags, along with the number of test cases they match. Again, supplying test specs limits the tags that match. ```--list-reporters``` lists the available reporters. ## Sending output to a file
-o, --out <filename>
Use this option to send all output to a file. By default output is sent to stdout (note that uses of stdout and stderr *from within test cases* are redirected and included in the report - so even stderr will effectively end up on stdout). ## Naming a test run
-n, --name <name for test run>
If a name is supplied it will be used by the reporter to provide an overall name for the test run. This can be useful if you are sending to a file, for example, and need to distinguish different test runs - either from different Catch executables or runs of the same executable with different options. If not supplied the name is defaulted to the name of the executable. ## Eliding assertions expected to throw
-e, --nothrow
Skips all assertions that test that an exception is thrown, e.g. ```REQUIRE_THROWS```. These can be a nuisance in certain debugging environments that may break when exceptions are thrown (while this is usually optional for handled exceptions, it can be useful to have enabled if you are trying to track down something unexpected). Sometimes exceptions are expected outside of one of the assertions that tests for them (perhaps thrown and caught within the code-under-test). The whole test case can be skipped when using ```-e``` by marking it with the ```[!throws]``` tag. When running with this option any throw checking assertions are skipped so as not to contribute additional noise. Be careful if this affects the behaviour of subsequent tests. ## Make whitespace visible
-i, --invisibles
If a string comparison fails due to differences in whitespace - especially leading or trailing whitespace - it can be hard to see what's going on. This option transforms tabs and newline characters into ```\t``` and ```\n``` respectively when printing. ## Warnings
-w, --warn <warning name>
Enables reporting of warnings (only one, at time of this writing). If a warning is issued it fails the test. The ony available warning, presently, is ```NoAssertions```. This warning fails a test case, or (leaf) section if no assertions (```REQUIRE```/ ```CHECK``` etc) are encountered. ## Reporting timings
-d, --durations <yes/no>
When set to ```yes``` Catch will report the duration of each test case, in milliseconds. Note that it does this regardless of whether a test case passes or fails. Note, also, the certain reporters (e.g. Junit) always report test case durations regardless of this option being set or not. ## Load test names to run from a file
-f, --input-file <filename>
Provide the name of a file that contains a list of test case names - one per line. Blank lines are skipped and anything after the comment character, ```#```, is ignored. A useful way to generate an initial instance of this file is to use the list-test-names-only option. This can then be manually curated to specify a specific subset of tests - or in a specific order. ## Just test names
--list-test-names-only
This option lists all available tests in a non-indented form, one on each line. This makes it ideal for saving to a file and feeding back into the ```-f``` or ```--input-file``` option. ## Specify the order test cases are run
--order <decl|lex|rand>
Test cases are ordered one of three ways: ### decl Declaration order. The order the tests were originally declared in. Note that ordering between files is not guaranteed and is implementation dependent. ### lex Lexicographically sorted. Tests are sorted, alpha-numerically, by name. ### rand Randomly sorted. Test names are sorted using ```std::random_shuffle()```. By default the random number generator is seeded with 0 - and so the order is repeatable. To control the random seed see rng-seed. ## Specify a seed for the Random Number Generator
--rng-seed <'time'|number>
Sets a seed for the random number generator using ```std::srand()```. If a number is provided this is used directly as the seed so the random pattern is repeatable. Alternatively if the keyword ```time``` is provided then the result of calling ```std::time(0)``` is used and so the pattern becomes unpredictable. In either case the actual value for the seed is printed as part of Catch's output so if an issue is discovered that is sensitive to test ordering the ordering can be reproduced - even if it was originally seeded from ```std::time(0)```. ## Identify framework and version according to the libIdentify standard
--libidentify
See [The LibIdentify repo for more information and examples](https://github.com/janwilmans/LibIdentify). ## Wait for key before continuing
--wait-for-keypress <start|exit|both>
Will cause the executable to print a message and wait until the return/ enter key is pressed before continuing - either before running any tests, after running all tests - or both, depending on the argument. ## Usage
-h, -?, --help
Prints the command line arguments to stdout ## Specify the section to run
-c, --section <section name>
To limit execution to a specific section within a test case, use this option one or more times. To narrow to sub-sections use multiple instances, where each subsequent instance specifies a deeper nesting level. E.g. if you have:
TEST_CASE( "Test" ) {
  SECTION( "sa" ) {
    SECTION( "sb" ) {
      /*...*/
    }
    SECTION( "sc" ) {
      /*...*/
    }
  }
  SECTION( "sd" ) {
    /*...*/
  }
}
Then you can run `sb` with:
./MyExe Test -c sa -c sb
Or run just `sd` with:
./MyExe Test -c sd
To run all of `sa`, including `sb` and `sc` use:
./MyExe Test -c sa
There are some limitations of this feature to be aware of: - Code outside of sections being skipped will still be executed - e.g. any set-up code in the TEST_CASE before the start of the first section.
- At time of writing, wildcards are not supported in section names. - If you specify a section without narrowing to a test case first then all test cases will be executed (but only matching sections within them). ## Filenames as tags
-#, --filenames-as-tags
When this option is used then every test is given an additional tag which is formed of the unqualified filename it is found in, with any extension stripped, prefixed with the `#` character. So, for example, tests within the file `~\Dev\MyProject\Ferrets.cpp` would be tagged `[#Ferrets]`. --- [Home](Readme.md) catch-1.12.1/docs/commercial-users.md000066400000000000000000000016241325474075300174170ustar00rootroot00000000000000# Commercial users of Catch As well as [Open Source](opensource-users.md) users Catch is widely used within proprietary code bases too. Many organisations like to keep this information internal, and that's fine, but if you're more open it would be great if we could list the names of as many organisations as possible that use Catch somewhere in their codebase. Enterprise environments often tend to be far more conservative in their tool adoption - and being aware that other companies are using Catch can ease the path in. So if you are aware of Catch usage in your organisation, and are fairly confident there is no issue with sharing this fact then please let us know - either directly, via a PR or [issue](https://github.com/philsquared/Catch/issues), or on the [forums](https://groups.google.com/forum/?fromgroups#!forum/catch-forum). - Bloomberg - NASA - [Inscopix Inc.](https://www.inscopix.com/) catch-1.12.1/docs/configuration.md000066400000000000000000000211711325474075300170130ustar00rootroot00000000000000Catch is designed to "just work" as much as possible. For most people the only configuration needed is telling Catch which source file should host all the implementation code (```CATCH_CONFIG_MAIN```). Nonetheless there are still some occasions where finer control is needed. For these occasions Catch exposes a set of macros for configuring how it is built. # main()/ implementation CATCH_CONFIG_MAIN // Designates this as implementation file and defines main() CATCH_CONFIG_RUNNER // Designates this as implementation file Although Catch is header only it still, internally, maintains a distinction between interface headers and headers that contain implementation. Only one source file in your test project should compile the implementation headers and this is controlled through the use of one of these macros - one of these identifiers should be defined before including Catch in *exactly one implementation file in your project*. # Prefixing Catch macros CATCH_CONFIG_PREFIX_ALL To keep test code clean and uncluttered Catch uses short macro names (e.g. ```TEST_CASE``` and ```REQUIRE```). Occasionally these may conflict with identifiers from platform headers or the system under test. In this case the above identifier can be defined. This will cause all the Catch user macros to be prefixed with ```CATCH_``` (e.g. ```CATCH_TEST_CASE``` and ```CATCH_REQUIRE```). # Terminal colour CATCH_CONFIG_COLOUR_NONE // completely disables all text colouring CATCH_CONFIG_COLOUR_WINDOWS // forces the Win32 console API to be used CATCH_CONFIG_COLOUR_ANSI // forces ANSI colour codes to be used Yes, I am English, so I will continue to spell "colour" with a 'u'. When sending output to the terminal, if it detects that it can, Catch will use colourised text. On Windows the Win32 API, ```SetConsoleTextAttribute```, is used. On POSIX systems ANSI colour escape codes are inserted into the stream. For finer control you can define one of the above identifiers (these are mutually exclusive - but that is not checked so may behave unexpectedly if you mix them): Note that when ANSI colour codes are used "unistd.h" must be includable - along with a definition of ```isatty()``` Typically you should place the ```#define``` before #including "catch.hpp" in your main source file - but if you prefer you can define it for your whole project by whatever your IDE or build system provides for you to do so. # Console width CATCH_CONFIG_CONSOLE_WIDTH = x // where x is a number Catch formats output intended for the console to fit within a fixed number of characters. This is especially important as indentation is used extensively and uncontrolled line wraps break this. By default a console width of 80 is assumed but this can be controlled by defining the above identifier to be a different value. # stdout CATCH_CONFIG_NOSTDOUT Catch does not use ```std::cout```, ```std::cerr``` and ```std::clog``` directly but gets them from ```Catch::cout()```, ```Catch::cerr()``` and ```Catch::clog``` respectively. If the above identifier is defined these functions are left unimplemented and you must implement them yourself. Their signatures are: std::ostream& cout(); std::ostream& cerr(); std::ostream& clog(); This can be useful on certain platforms that do not provide the standard iostreams, such as certain embedded systems. # Default reporter CATCH_CONFIG_DEFAULT_REPORTER The default reporter (reporter used when no reporters are explicitly specified) can be overriden during compilation time by using the above macro. Note that desired value of the macro is a C string and quotes have to be escaped during compilation: `clang++ test.cpp -DCATCH_CONFIG_DEFAULT_REPORTER=\"xml\"`. # C++ conformance toggles CATCH_CONFIG_CPP11_NULLPTR // nullptr is supported? CATCH_CONFIG_CPP11_NOEXCEPT // noexcept is supported? CATCH_CONFIG_CPP11_GENERATED_METHODS // delete and default keywords for methods CATCH_CONFIG_CPP11_IS_ENUM // std::is_enum is supported? CATCH_CONFIG_CPP11_TUPLE // std::tuple is supported CATCH_CONFIG_VARIADIC_MACROS // Usually pre-C++11 compiler extensions are sufficient CATCH_CONFIG_CPP11_LONG_LONG // generates overloads for the long long type CATCH_CONFIG_CPP11_OVERRIDE // CATCH_OVERRIDE expands to override (for virtual function implementations) CATCH_CONFIG_CPP11_UNIQUE_PTR // Use std::unique_ptr instead of std::auto_ptr CATCH_CONFIG_CPP11_SHUFFLE // Use std::shuffle instead of std::random_shuffle CATCH_CONFIG_CPP11_TYPE_TRAITS // Use std::enable_if and CATCH_CONFIG_CPP11_STREAM_INSERTABLE_CHECK // Use C++11 expression SFINAE to check if class can be inserted to std::ostream Catch has some basic compiler detection that will attempt to select the appropriate mix of these macros. However being incomplete - and often without access to the respective compilers - this detection tends to be conservative. So overriding control is given to the user. If a compiler supports a feature (and Catch does not already detect it) then one or more of these may be defined to enable it (or suppress it, in some cases). If you do do this please raise an issue, specifying your compiler version (ideally with an idea of how to detect it) and stating that it has such support. You may also suppress any of these features by using the `_NO_` form, e.g. `CATCH_CONFIG_CPP11_NO_NULLPTR`. All C++11 support can be disabled with `CATCH_CONFIG_NO_CPP11` ## `CATCH_CONFIG_CPP11_STREAM_INSERTABLE_CHECK` This flag is off by default, but allows you to resolve problems caused by types with private base class that are streamable, but the classes themselves are not. Without it, the following code will cause a compilation error: ```cpp #define CATCH_CONFIG_MAIN #include struct A {}; std::ostream &operator<< (std::ostream &o, const A &v) { return o << 0; } struct B : private A { bool operator==(int){ return true;} }; B f (); std::ostream g (); TEST_CASE ("Error in streamable check") { B x; REQUIRE (x == 4); } ``` # Other toggles CATCH_CONFIG_COUNTER // Use __COUNTER__ to generate unique names for test cases CATCH_CONFIG_WINDOWS_SEH // Enable SEH handling on Windows CATCH_CONFIG_FAST_COMPILE // Sacrifices some (rather minor) features for compilation speed CATCH_CONFIG_POSIX_SIGNALS // Enable handling POSIX signals CATCH_CONFIG_WINDOWS_CRTDBG // Enable leak checking using Windows's CRT Debug Heap CATCH_CONFIG_DISABLE_STRINGIFICATION // Disable stringifying the original expression Currently Catch enables `CATCH_CONFIG_WINDOWS_SEH` only when compiled with MSVC, because some versions of MinGW do not have the necessary Win32 API support. `CATCH_CONFIG_POSIX_SIGNALS` is on by default, except when Catch is compiled under `Cygwin`, where it is disabled by default (but can be force-enabled by defining `CATCH_CONFIG_POSIX_SIGNALS`). `CATCH_CONFIG_WINDOWS_CRTDBG` is off by default. If enabled, Windows's CRT is used to check for memory leaks, and displays them after the tests finish running. Just as with the C++11 conformance toggles, these toggles can be disabled by using `_NO_` form of the toggle, e.g. `CATCH_CONFIG_NO_WINDOWS_SEH`. ## `CATCH_CONFIG_FAST_COMPILE` Defining this flag speeds up compilation of test files by ~20%, by making 2 changes: * The `-b` (`--break`) flag no longer makes Catch break into debugger in the same stack frame as the failed test, but rather in a stack frame *below*. * The `REQUIRE` family of macros (`REQUIRE`, `REQUIRE_FALSE` and `REQUIRE_THAT`) no longer uses local try-catch block. This disables exception translation, but should not lead to false negatives. `CATCH_CONFIG_FAST_COMPILE` has to be either defined, or not defined, in all translation units that are linked into single test binary, or the behaviour of setting `-b` flag and throwing unexpected exceptions will be unpredictable. ## `CATCH_CONFIG_DISABLE_STRINGIFICATION` This toggle enables a workaround for VS 2017 bug. For details see [known limitations](limitations.md#visual-studio-2017----raw-string-literal-in-assert-fails-to-compile). # Windows header clutter On Windows Catch includes `windows.h`. To minimize global namespace clutter in the implementation file, it defines `NOMINMAX` and `WIN32_LEAN_AND_MEAN` before including it. You can control this behaviour via two macros: CATCH_CONFIG_NO_NOMINMAX // Stops Catch from using NOMINMAX macro CATCH_CONFIG_NO_WIN32_LEAN_AND_MEAN // Stops Catch from using WIN32_LEAN_AND_MEAN macro --- [Home](Readme.md) catch-1.12.1/docs/contributing.md000066400000000000000000000064621325474075300166610ustar00rootroot00000000000000# Contributing to Catch So you want to contribute something to Catch? That's great! Whether it's a bug fix, a new feature, support for additional compilers - or just a fix to the documentation - all contributions are very welcome and very much appreciated. Of course so are bug reports and other comments and questions. If you are contributing to the code base there are a few simple guidelines to keep in mind. This also includes notes to help you find your way around. As this is liable to drift out of date please raise an issue or, better still, a pull request for this file, if you notice that. ## Branches Ongoing development is currently on _master_. At some point an integration branch will be set-up and PRs should target that - but for now it's all against master. You may see feature branches come and go from time to time, too. ## Directory structure _Users_ of Catch primarily use the single header version. _Maintainers_ should work with the full source (which is still, primarily, in headers). This can be found in the `include` folder. There are a set of test files, currently under `projects/SelfTest`. The test app can be built via CMake from the `CMakeLists.txt` file in the root, or you can generate project files for Visual Studio, XCode, and others (instructions in the `projects` folder). If you have access to CLion, it can work with the CMake file directly. As well as the runtime test files you'll also see a `SurrogateCpps` directory under `projects/SelfTest`. This contains a set of .cpp files that each `#include` a single header. While these files are not essential to compilation they help to keep the implementation headers self-contained. At time of writing this set is not complete but has reasonable coverage. If you add additional headers please try to remember to add a surrogate cpp for it. The other directories are `scripts` which contains a set of python scripts to help in testing Catch as well as generating the single include, and `docs`, which contains the documentation as a set of markdown files. __When submitting a pull request please do not include changes to the single include, or to the version number file as these are managed by the scripts!__ ## Testing your changes Obviously all changes to Catch's code should be tested. If you added new functionality, you should add tests covering and showcasing it. Even if you have only made changes to Catch internals (ie you implemented some performance improvements), you should still test your changes. This means 3 things * Compiling Catch's SelfTest project -- code that does not compile is evidently incorrect. Obviously, you are not expected to have access to all compilers and platforms Catch supports, Catch's CI pipeline will compile your code using supported compilers once you open a PR. * Running the SelfTest binary. There should be no unexpected failures on simple run. * Running Catch's approval tests. Approval tests compare current output of the SelfTest binary in various configurations against known good output. Catch's repository provides utility scripts `approvalTests.py` to help you with this. It needs to be passed the SelfTest binary compiled with your changes, like so: `$ ./scripts/approvalTests.py clang-build/SelfTest`. The output should be fairly self-explanatory. *this document is still in-progress...* --- [Home](Readme.md)catch-1.12.1/docs/event-listeners.md000066400000000000000000000052121325474075300172710ustar00rootroot00000000000000# Event Listeners A `Listener` is a class you can register with Catch that will then be passed events, such as a test case starting or ending, as they happen during a test run. `Listeners` are actually types of `Reporters`, with a few small differences: 1. Once registered in code they are automatically used - you don't need to specify them on the command line 2. They are called in addition to (just before) any reporters, and you can register multiple listeners. 3. They derive from `Catch::TestEventListenerBase`, which has default stubs for all the events, so you are not forced to implement events you're not interested in. 4. You register a listener with `CATCH_REGISTER_LISTENER` ## Implementing a Listener In your main source file (i.e. the one that has the `#define` for `CATCH_CONFIG_MAIN` or `CATCH_CONFIG_RUNNER`), simply derive a class from `Catch::TestEventListenerBase` and implement the methods you are interested in. Then register it using `INTERNAL_CATCH_REGISTER_LISTENER`. For example: ```c++ #define CATCH_CONFIG_MAIN #include "catch.hpp" struct MyListener : Catch::TestEventListenerBase { using TestEventListenerBase::TestEventListenerBase; // inherit constructor virtual void testCaseStarting( Catch::TestCaseInfo const& testInfo ) override { // Perform some setup before a test case is run } virtual void testCaseEnded( Catch::TestCaseStats const& testCaseStats ) override { // Tear-down after a test case is run } }; CATCH_REGISTER_LISTENER( MyListener ) ``` _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: ```c++ // The whole test run, starting and ending virtual void testRunStarting( TestRunInfo const& testRunInfo ); virtual void testRunEnded( TestRunStats const& testRunStats ); // Test cases starting and ending virtual void testCaseStarting( TestCaseInfo const& testInfo ); virtual void testCaseEnded( TestCaseStats const& testCaseStats ); // Sections starting and ending virtual void sectionStarting( SectionInfo const& sectionInfo ); virtual void sectionEnded( SectionStats const& sectionStats ); // Assertions before/ after virtual void assertionStarting( AssertionInfo const& assertionInfo ); virtual bool assertionEnded( AssertionStats const& assertionStats ); // A test is being skipped (because it is "hidden") virtual void skipTest( TestCaseInfo const& testInfo ); ``` More information about the events (e.g. name of the test case) is contained in the structs passed as arguments - just look in the source code to see what fields are available. --- [Home](Readme.md) catch-1.12.1/docs/limitations.md000066400000000000000000000126021325474075300164770ustar00rootroot00000000000000# Known limitations Catch has some known limitations, that we are not planning to change. Some of these are caused by our desire to support C++98 compilers, some of these are caused by our desire to keep Catch crossplatform, some exist because their priority is seen as low compared to the development effort they would need and some other yet are compiler/runtime bugs. ## Features This section outlines some missing features, what is their status and their possible workarounds. ### Thread safe assertions Because threading support in standard C++98 is limited (well, non-existent), assertion macros in Catch are not thread safe. This does not mean that you cannot use threads inside Catch's test, but that only single thread can interact with Catch's assertions and other macros. This means that this is ok ```cpp std::vector threads; std::atomic cnt{ 0 }; for (int i = 0; i < 4; ++i) { threads.emplace_back([&]() { ++cnt; ++cnt; ++cnt; ++cnt; }); } for (auto& t : threads) { t.join(); } REQUIRE(cnt == 16); ``` because only one thread passes the `REQUIRE` macro and this is not ```cpp std::vector threads; std::atomic cnt{ 0 }; for (int i = 0; i < 4; ++i) { threads.emplace_back([&]() { ++cnt; ++cnt; ++cnt; ++cnt; CHECK(cnt == 16); }); } for (auto& t : threads) { t.join(); } REQUIRE(cnt == 16); ``` _This limitation is highly unlikely to be lifted before Catch 2 is released._ ### Process isolation in a test Catch does not support running tests in isolated (forked) processes. While this might in the future, the fact that Windows does not support forking and only allows full-on process creation and the desire to keep code as similar as possible across platforms, mean that this is likely to take significant development time, that is not currently available. ### Running multiple tests in parallel Catch's test execution is strictly serial. If you find yourself with a test suite that takes too long to run and you want to make it parallel, there are 2 feasible solutions * You can split your tests into multiple binaries and then run these binaries in parallel. * You can have Catch list contained test cases and then run the same test binary multiple times in parallel, passing each instance list of test cases it should run. Both of these solutions have their problems, but should let you wring parallelism out of your test suite. ## 3rd party bugs This section outlines known bugs in 3rd party components (this means compilers, standard libraries, standard runtimes). ### Visual Studio 2017 -- raw string literal in assert fails to compile There is a known bug in Visual Studio 2017 (VC 15), that causes compilation error when preprocessor attempts to stringize a raw string literal (`#` preprocessor is applied to it). This snippet is sufficient to trigger the compilation error: ```cpp #define CATCH_CONFIG_MAIN #include "catch.hpp" TEST_CASE("test") { CHECK(std::string(R"("\)") == "\"\\"); } ``` Catch provides a workaround, it is possible to disable stringification of original expressions by defining `CATCH_CONFIG_DISABLE_STRINGIFICATION`: ```cpp #define CATCH_CONFIG_FAST_COMPILE #define CATCH_CONFIG_DISABLE_STRINGIFICATION #include "catch.hpp" TEST_CASE("test") { CHECK(std::string(R"("\)") == "\"\\"); } ``` _Do note that this changes the output somewhat_ ``` catchwork\test1.cpp(6): PASSED: CHECK( Disabled by CATCH_CONFIG_DISABLE_STRINGIFICATION ) with expansion: ""\" == ""\" ``` ### Visual Studio 2013 -- do-while loop withing range based for fails to compile (C2059) There is a known bug in Visual Studio 2013 (VC 12), that causes compilation error if range based for is followed by an assertion macro, without enclosing the block in braces. This snippet is sufficient to trigger the error ```cpp #define CATCH_CONFIG_MAIN #include "catch.hpp" TEST_CASE("Syntax error with VC12") { for ( auto x : { 1 , 2, 3 } ) REQUIRE( x < 3.14 ); } ``` An easy workaround is possible, use braces: ```cpp #define CATCH_CONFIG_MAIN #include "catch.hpp" TEST_CASE("No longer a syntax error with VC12") { for ( auto x : { 1 , 2, 3 } ) { REQUIRE( x < 3.14 ); } } ``` ### Visual Studio 2003 -- Syntax error caused by improperly expanded `__LINE__` macro Older version of Visual Studio can have trouble compiling Catch, not expanding the `__LINE__` macro properly when recompiling the test binary. This is caused by Edit and Continue being on. A workaround is to turn off Edit and Continue when compiling the test binary. ### Clang/G++ -- skipping leaf sections after an exception Some versions of `libc++` and `libstdc++` (or their runtimes) have a bug with `std::uncaught_exception()` getting stuck returning `true` after rethrow, even if there are no active exceptions. One such case is this snippet, which skipped the sections "a" and "b", when compiled against `libcxxrt` from master ```cpp #define CATCH_CONFIG_MAIN #include TEST_CASE("a") { CHECK_THROWS(throw 3); } TEST_CASE("b") { int i = 0; SECTION("a") { i = 1; } SECTION("b") { i = 2; } CHECK(i > 0); } ``` If you are seeing a problem like this, i.e. a weird test paths that trigger only under Clang with `libc++`, or only under very specific version of `libstdc++`, it is very likely you are seeing this. The only known workaround is to use a fixed version of your standard library. catch-1.12.1/docs/logging.md000066400000000000000000000046201325474075300155720ustar00rootroot00000000000000# Logging macros Additional messages can be logged during a test case. Note that the messages are scoped and thus will not be reported if failure occurs in scope preceding the message declaration. An example: ```cpp TEST_CASE("Foo") { INFO("Test case start"); for (int i = 0; i < 2; ++i) { INFO("The number is " << i); CHECK(i == 0); } } TEST_CASE("Bar") { INFO("Test case start"); for (int i = 0; i < 2; ++i) { INFO("The number is " << i); CHECK(i == i); } CHECK(false); } ``` When the `CHECK` fails in the "Foo" test case, then two messages will be printed. ``` Test case start The number is 1 ``` When the last `CHECK` fails in the "Bar" test case, then only one message will be printed: `Test case start`. ## Streaming macros All these macros allow heterogenous sequences of values to be streaming using the insertion operator (```<<```) in the same way that std::ostream, std::cout, etc support it. E.g.: ```c++ INFO( "The number is " << i ); ``` (Note that there is no initial ```<<``` - instead the insertion sequence is placed in parentheses.) These macros come in three forms: **INFO(** _message expression_ **)** The message is logged to a buffer, but only reported with the next assertion that is logged. This allows you to log contextual information in case of failures which is not shown during a successful test run (for the console reporter, without -s). Messages are removed from the buffer at the end of their scope, so may be used, for example, in loops. **WARN(** _message expression_ **)** The message is always reported but does not fail the test. **FAIL(** _message expression_ **)** The message is reported and the test case fails. **FAIL_CHECK(** _message expression_ **)** AS `FAIL`, but does not abort the test ## Quickly capture a variable value **CAPTURE(** _expression_ **)** Sometimes you just want to log the name and value of a variable. While you can easily do this with the INFO macro, above, as a convenience the CAPTURE macro handles the stringising of the variable name for you (actually it works with any expression, not just variables). E.g. ```c++ CAPTURE( theAnswer ); ``` This would log something like:
"theAnswer := 42"
## Deprecated macros **SCOPED_INFO and SCOPED_CAPTURE** These macros are now deprecated and are just aliases for INFO and CAPTURE (which were not previously scoped). --- [Home](Readme.md)catch-1.12.1/docs/matchers.md000066400000000000000000000072461325474075300157610ustar00rootroot00000000000000# Matchers Matchers are an alternative way to do assertions which are easily extensible and composable. This makes them well suited to use with more complex types (such as collections) or your own custom types. Matchers were first popularised by the [Hamcrest](https://en.wikipedia.org/wiki/Hamcrest) family of frameworks. ## In use Matchers are introduced with the `REQUIRE_THAT` or `CHECK_THAT` macros, which take two arguments. The first argument is the thing (object or value) under test. The second part is a match _expression_, which consists of either a single matcher or one or more matchers combined using `&&`, `||` or `!` operators. For example, to assert that a string ends with a certain substring: ```c++ using Catch::Matchers::EndsWith; // or Catch::EndsWith std::string str = getStringFromSomewhere(); REQUIRE_THAT( str, EndsWith( "as a service" ) ); ``` The matcher objects can take multiple arguments, allowing more fine tuning. The built-in string matchers, for example, take a second argument specifying whether the comparison is case sensitive or not: ```c++ REQUIRE_THAT( str, EndsWith( "as a service", Catch::CaseSensitive::No ) ); ``` And matchers can be combined: ```c++ REQUIRE_THAT( str, EndsWith( "as a service" ) || (StartsWith( "Big data" ) && !Contains( "web scale" ) ) ); ``` ## Built in matchers Currently Catch has some string matchers and some vector matchers. They are in the `Catch::Matchers` and `Catch` namespaces. The string matchers are `StartsWith`, `EndsWith`, `Contains` and `Equals`. Each of them also takes an optional second argument, that decides case sensitivity (by-default, they are case sensitive). The vector matchers are `Contains`, `VectorContains` and `Equals`. `VectorContains` looks for a single element in the matched vector, `Contains` looks for a set (vector) of elements inside the matched vector. ## Custom matchers It's easy to provide your own matchers to extend Catch or just to work with your own types. You need to provide two things: 1. A matcher class, derived from `Catch::MatcherBase` - where `T` is the type being tested. The constructor takes and stores any arguments needed (e.g. something to compare against) and you must override two methods: `match()` and `describe()`. 2. A simple builder function. This is what is actually called from the test code and allows overloading. Here's an example for asserting that an integer falls within a given range (note that it is all inline for the sake of keeping the example short): ```c++ // The matcher class class IntRange : public Catch::MatcherBase { int m_begin, m_end; public: IntRange( int begin, int end ) : m_begin( begin ), m_end( end ) {} // Performs the test for this matcher virtual bool match( int const& i ) const override { return i >= m_begin && i <= m_end; } // Produces a string describing what this matcher does. It should // include any provided data (the begin/ end in this case) and // be written as if it were stating a fact (in the output it will be // preceded by the value under test). virtual std::string describe() const { std::ostringstream ss; ss << "is between " << m_begin << " and " << m_end; return ss.str(); } }; // The builder function inline IntRange IsBetween( int begin, int end ) { return IntRange( begin, end ); } // ... // Usage TEST_CASE("Integers are within a range") { CHECK_THAT( 3, IsBetween( 1, 10 ) ); CHECK_THAT( 100, IsBetween( 1, 10 ) ); } ``` Running this test gives the following in the console: ``` /**/TestFile.cpp:123: FAILED: CHECK_THAT( 100, IsBetween( 1, 10 ) ) with expansion: 100 is between 1 and 10 ``` --- [Home](Readme.md)catch-1.12.1/docs/opensource-users.md000066400000000000000000000101311325474075300174570ustar00rootroot00000000000000# Open Source projects using Catch Catch is great for open source. With its [liberal license](../LICENSE.txt) and single-header, dependency-free, distribution it's easy to just drop the header into your project and start writing tests - what's not to like? As a result Catch is now being used in many Open Source projects, including some quite well known ones. This page is an attempt to track those projects. Obviously it can never be complete. This effort largely relies on the maintainers of the projects themselves updating this page and submitting a PR (or, if you prefer contact one of the maintainers of Catch directly, use the [forums](https://groups.google.com/forum/?fromgroups#!forum/catch-forum)), or raise an [issue](https://github.com/philsquared/Catch/issues) to let us know). Of course users of those projects might want to update this page too. That's fine - as long you're confident the project maintainers won't mind. If you're an Open Source project maintainer and see your project listed here but would rather it wasn't - just let us know via any of the previously mentioned means - although I'm sure there won't be many who feel that way. Listing a project here does not imply endorsement and the plan is to keep these ordered alphabetically to avoid an implication of relative importance. ## Libraries & Frameworks ### [Azmq](https://github.com/zeromq/azmq) Boost Asio style bindings for ZeroMQ ### [ChakraCore](https://github.com/Microsoft/ChakraCore) 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 ### [Clara](https://github.com/philsquared/Clara) A, single-header-only, type-safe, command line parser - which also prints formatted usage strings. ### [Couchbase-lite-core](https://github.com/couchbase/couchbase-lite-core) The next-generation core storage and query engine for Couchbase Lite/ ### [JSON for Modern C++](https://github.com/nlohmann/json) A, single-header, JSON parsing library that takes advantage of what C++ has to offer. ### [MNMLSTC Core](https://github.com/mnmlstc/core) a small and easy to use C++11 library that adds a functionality set that will be available in C++14 and later, as well as some useful additions ### [nanodbc](https://github.com/lexicalunit/nanodbc/) A small C++ library wrapper for the native C ODBC API. ### [Nonius](https://github.com/libnonius/nonius) A header-only framework for benchmarking small snippets of C++ code. ### [SOCI](https://github.com/SOCI/soci) The C++ Database Access Library ### [polymorphic_value](https://github.com/jbcoe/polymorphic_value) A polymorphic value-type for C++ ### [Ppconsul](https://github.com/oliora/ppconsul) A C++ client library for Consul. Consul is a distributed tool for discovering and configuring services in your infrastructure ### [Reactive-Extensions/ RxCpp](https://github.com/Reactive-Extensions/RxCpp) A library of algorithms for values-distributed-in-time ### [TextFlowCpp](https://github.com/philsquared/textflowcpp) A small, single-header-only, library for wrapping and composing columns of text ### [Trompeloeil](https://github.com/rollbear/trompeloeil) A thread safe header only mocking framework for C++14 ### [args](https://github.com/Taywee/args) A simple header-only C++ argument parser library. ## Applications & Tools ### [ArangoDB](https://github.com/arangodb/arangodb) ArangoDB is a native multi-model database with flexible data models for documents, graphs, and key-values. ### [Giada - Your Hardcore Loop Machine](https://github.com/monocasual/giada) Minimal, open-source and cross-platform audio tool for live music production. ### [MAME](https://github.com/mamedev/mame) MAME originally stood for Multiple Arcade Machine Emulator ### [Newsbeuter](https://github.com/akrennmair/newsbeuter) Newsbeuter is an open-source RSS/Atom feed reader for text terminals. ### [Standardese](https://github.com/foonathan/standardese) Standardese aims to be a nextgen Doxygen --- [Home](Readme.md) catch-1.12.1/docs/own-main.md000066400000000000000000000045211325474075300156710ustar00rootroot00000000000000# Supplying main() yourself The easiest way to use Catch is to let it supply ```main()``` for you and handle configuring itself from the command line. This is achieved by writing ```#define CATCH_CONFIG_MAIN``` before the ```#include "catch.hpp"``` in *exactly one* source file. Sometimes, though, you need to write your own version of main(). You can do this by writing ```#define CATCH_CONFIG_RUNNER``` instead. Now you are free to write ```main()``` as normal and call into Catch yourself manually. You now have a lot of flexibility - but here are three recipes to get your started: ## Let Catch take full control of args and config If you just need to have code that executes before and/ or after Catch this is the simplest option. ```c++ #define CATCH_CONFIG_RUNNER #include "catch.hpp" int main( int argc, char* argv[] ) { // global setup... int result = Catch::Session().run( argc, argv ); // global clean-up... return ( result < 0xff ? result : 0xff ); } ``` ## 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: ```c++ #define CATCH_CONFIG_RUNNER #include "catch.hpp" int main( int argc, char* argv[] ) { Catch::Session session; // There must be exactly one instance // writing to session.configData() here sets defaults // this is the preferred way to set them int returnCode = session.applyCommandLine( argc, argv ); if( returnCode != 0 ) // Indicates a command line error return returnCode; // writing to session.configData() or session.Config() here // overrides command line args // only do this if you know you need to int numFailed = session.run(); // Note that on unices only the lower 8 bits are usually used, clamping // the return value to 255 prevents false negative when some multiple // of 256 tests has failed return ( numFailed < 0xff ? numFailed : 0xff ); } ``` Take a look at the definitions of Config and ConfigData to see what you can do with them. To take full control of the config simply omit the call to ```applyCommandLine()```. ## Adding your own command line options Catch embeds a powerful command line parser which you can also use to parse your own options out. This capability is still in active development but will be documented here when it is ready. --- [Home](Readme.md) catch-1.12.1/docs/release-notes.md000066400000000000000000000402471325474075300167170ustar00rootroot00000000000000# 1.12.1 ### Fixes * Fixed deprecation warning in `ScopedMessage::~ScopedMessage` * All uses of `min` or `max` identifiers are now wrapped in parentheses * This avoids problems when Windows headers define `min` and `max` macros # 1.12.0 ### Fixes * Fixed compilation for strict C++98 mode (ie not gnu++98) and older compilers (#1103) * `INFO` messages are included in the `xml` reporter output even without `-s` specified. # 1.11.0 ### Fixes * The original expression in `REQUIRE_FALSE( expr )` is now reporter properly as `!( expr )` (#1051) * Previously the parentheses were missing and `x != y` would be expanded as `!x != x` * `Approx::Margin` is now inclusive (#952) * Previously it was meant and documented as inclusive, but the check itself wasn't * This means that `REQUIRE( 0.25f == Approx( 0.0f ).margin( 0.25f ) )` passes, instead of fails * `RandomNumberGenerator::result_type` is now unsigned (#1050) ### Improvements * `__JETBRAINS_IDE__` macro handling is now CLion version specific (#1017) * When CLion 2017.3 or newer is detected, `__COUNTER__` is used instead of * TeamCity reporter now explicitly flushes output stream after each report (#1057) * On some platforms, output from redirected streams would show up only after the tests finished running * `ParseAndAddCatchTests` now can add test files as dependency to CMake configuration * This means you do not have to manually rerun CMake configuration step to detect new tests # 1.10.0 ### Fixes * Evaluation layer has been rewritten (backported from Catch 2) * The new layer is much simpler and fixes some issues (#981) * Implemented workaround for VS 2017 raw string literal stringification bug (#995) * Fixed interaction between `[!shouldfail]` and `[!mayfail]` tags and sections * Previously sections with failing assertions would be marked as failed, not failed-but-ok ### Improvements * Added [libidentify](https://github.com/janwilmans/LibIdentify) support * Added "wait-for-keypress" option # 1.9.7 ### Fixes * Various warnings from clang-tidy, Resharper-C++ and PVS Studio have been addressed (#957) * Dynamically generated sections are now properly reported (#963) * Writes to `std::clog` are redirected for reporters (#989) * Previously only `std::cerr` writes were redirected * Interleaved writes to `std::cerr` and `std::clog` are combined properly * Assertions failed before signals/structured exceptions fails test case are properly reported as failed (#990) ### Improvements * Catch's runtime overhead has been decreased further (#940) * Added support for IBM i ILE c++ compiler (#976) * This means that AS/400 is now supported. * The default reporter can be configured at compile time (#978) * That is, the reporter used if no reporter is explicitly specified ### Other * `ParseAndAddCatchTests` cmake script has couple new customization options # 1.9.6 ### Improvements * Catch's runtime overhead has been significantly decreased (#937, #939) * Added `--list-extra-info` cli option (#934). * It lists all tests together with extra information, ie filename, line number and description. # 1.9.5 ### Fixes * Truthy expressions are now reconstructed properly, not as booleans (#914) * Various warnings are no longer erroneously suppressed in test files (files that include `catch.hpp`, but do not define `CATCH_CONFIG_MAIN` or `CATCH_CONFIG_RUNNER`) (#871) * Catch no longer fails to link when main is compiled as C++, but linked against Objective-C (#855) * Fixed incorrect gcc version detection when deciding to use `__COUNTER__` (#928) * Previously any GCC with minor version less than 3 would be incorrectly classified as not supporting `__COUNTER__`. * Suppressed C4996 warning caused by upcoming updated to MSVC 2017, marking `std::uncaught_exception` as deprecated. (#927) ### Improvements * CMake integration script now incorporates debug messages and registers tests in an improved way (#911) * Various documentation improvements # 1.9.4 ### Fixes * `CATCH_FAIL` macro no longer causes compilation error without variadic macro support * `INFO` messages are no longer cleared after being reported once ### Improvements and minor changes * Catch now uses `wmain` when compiled under Windows and `UNICODE` is defined. * Note that Catch still officially supports only ASCII # 1.9.3 ### Fixes * Completed the fix for (lack of) uint64_t in earlier Visual Studios # 1.9.2 ### Improvements and minor changes * All of `Approx`'s member functions now accept strong typedefs in C++11 mode (#888) * Previously `Approx::scale`, `Approx::epsilon`, `Approx::margin` and `Approx::operator()` didn't. ### Fixes * POSIX signals are now disabled by default under QNX (#889) * QNX does not support current enough (2001) POSIX specification * JUnit no longer counts exceptions as failures if given test case is marked as ok to fail. * `Catch::Option` should now have its storage properly aligned. * Catch no longer attempts to define `uint64_t` on windows (#862) * This was causing trouble when compiled under Cygwin ### Other * Catch is now compiled under MSVC 2017 using `std:c++latest` (C++17 mode) in CI * We now provide cmake script that autoregisters Catch tests into ctest. * See `contrib` folder. # 1.9.1 ### Fixes * Unexpected exceptions are no longer ignored by default (#885, #887) # 1.9.0 ### Improvements and minor changes * Catch no longer attempts to ensure the exception type passed by user in `REQUIRE_THROWS_AS` is a constant reference. * It was causing trouble when `REQUIRE_THROWS_AS` was used inside templated functions * This actually reverts changes made in v1.7.2 * Catch's `Version` struct should no longer be double freed when multiple instances of Catch tests are loaded into single program (#858) * It is now a static variable in an inline function instead of being an `extern`ed struct. * Attempt to register invalid tag or tag alias now throws instead of calling `exit()`. * Because this happen before entering main, it still aborts execution * Further improvements to this are coming * `CATCH_CONFIG_FAST_COMPILE` now speeds-up compilation of `REQUIRE*` assertions by further ~15%. * The trade-off is disabling translation of unexpected exceptions into text. * When Catch is compiled using C++11, `Approx` is now constructible with anything that can be explicitly converted to `double`. * Captured messages are now printed on unexpected exceptions ### Fixes: * Clang's `-Wexit-time-destructors` should be suppressed for Catch's internals * GCC's `-Wparentheses` is now suppressed for all TU's that include `catch.hpp`. * This is functionally a revert of changes made in 1.8.0, where we tried using `_Pragma` based suppression. This should have kept the suppression local to Catch's assertions, but bugs in GCC's handling of `_Pragma`s in C++ mode meant that it did not always work. * You can now tell Catch to use C++11-based check when checking whether a type can be streamed to output. * This fixes cases when an unstreamable type has streamable private base (#877) * [Details can be found in documentation](configuration.md#catch_config_cpp11_stream_insertable_check) ### Other notes: * We have added VS 2017 to our CI * Work on Catch 2 should start soon # 1.8.2 ### Improvements and minor changes * TAP reporter now behaves as if `-s` was always set * This should be more consistent with the protocol desired behaviour. * Compact reporter now obeys `-d yes` argument (#780) * The format is "XXX.123 s: " (3 decimal places are always present). * Before it did not report the durations at all. * XML reporter now behaves the same way as Console reporter in regards to `INFO` * This means it reports `INFO` messages on success, if output on success (`-s`) is enabled. * Previously it only reported `INFO` messages on failure. * `CAPTURE(expr)` now stringifies `expr` in the same way assertion macros do (#639) * Listeners are now finally [documented](event-listeners.md). * Listeners provide a way to hook into events generated by running your tests, including start and end of run, every test case, every section and every assertion. ### Fixes: * Catch no longer attempts to reconstruct expression that led to a fatal error (#810) * This fixes possible signal/SEH loop when processing expressions, where the signal was triggered by expression decomposition. * Fixed (C4265) missing virtual destructor warning in Matchers (#844) * `std::string`s are now taken by `const&` everywhere (#842). * Previously some places were taking them by-value. * Catch should no longer change errno (#835). * This was caused by libstdc++ bug that we now work around. * Catch now provides `FAIL_CHECK( ... )` macro (#765). * Same as `FAIL( ... )`, but does not abort the test. * Functions like `fabs`, `tolower`, `memset`, `isalnum` are now used with `std::` qualification (#543). * Clara no longer assumes first argument (binary name) is always present (#729) * If it is missing, empty string is used as default. * Clara no longer reads 1 character past argument string (#830) * Regression in Objective-C bindings (Matchers) fixed (#854) ### Other notes: * We have added VS 2013 and 2015 to our CI * Catch Classic (1.x.x) now contains its own, forked, version of Clara (the argument parser). # 1.8.1 ### Fixes Cygwin issue with `gettimeofday` - `#define` was not early enough # 1.8.0 ### New features/ minor changes * Matchers have new, simpler (and documented) interface. * Catch provides string and vector matchers. * For details see [Matchers documentation](matchers.md). * Changed console reporter test duration reporting format (#322) * Old format: `Some simple comparisons between doubles completed in 0.000123s` * New format: `xxx.123s: Some simple comparisons between doubles` _(There will always be exactly 3 decimal places)_ * Added opt-in leak detection under MSVC + Windows (#439) * Enable it by compiling Catch's main with `CATCH_CONFIG_WINDOWS_CRTDBG` * Introduced new compile-time flag, `CATCH_CONFIG_FAST_COMPILE`, trading features for compilation speed. * Moves debug breaks out of tests and into implementation, speeding up test compilation time (~10% on linux). * _More changes are coming_ * Added [TAP (Test Anything Protocol)](https://testanything.org/) and [Automake](https://www.gnu.org/software/automake/manual/html_node/Log-files-generation-and-test-results-recording.html#Log-files-generation-and-test-results-recording) reporters. * These are not present in the default single-include header and need to be downloaded from GitHub separately. * For details see [documentation about integrating with build systems](build-systems.md). * XML reporter now reports filename as part of the `Section` and `TestCase` tags. * `Approx` now supports an optional margin of absolute error * It has also received [new documentation](assertions.md). ### Fixes * Silenced C4312 ("conversion from int to 'ClassName *") warnings in the evaluate layer. * Fixed C4512 ("assignment operator could not be generated") warnings under VS2013. * 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 * Otherwise it is supressed for the whole TU * Fixed test spec parser issue (with escapes in multiple names) ### Other * Various documentation fixes and improvements # 1.7.2 ### Fixes and minor improvements Xml: (technically the first two are breaking changes but are also fixes and arguably break few if any people) * 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 * Tags are closed and the stream flushed more eagerly to avoid stdout interpolation Other: * `REQUIRE_THROWS_AS` now catches exception by `const&` and reports expected type * In `SECTION`s the file/ line is now of the `SECTION`. not the `TEST_CASE` * Added std:: qualification to some functions from C stdlib * Removed use of RTTI (`dynamic_cast`) that had crept back in * Silenced a few more warnings in different circumstances * Travis improvements # 1.7.1 ### Fixes: * Fixed inconsistency in defining `NOMINMAX` and `WIN32_LEAN_AND_MEAN` inside `catch.hpp`. * Fixed SEH-related compilation error under older MinGW compilers, by making Windows SEH handling opt-in for compilers other than MSVC. * For specifics, look into the [documentation](configuration.md). * Fixed compilation error under MinGW caused by improper compiler detection. * Fixed XML reporter sometimes leaving an empty output file when a test ends with signal/structured exception. * Fixed XML reporter not reporting captured stdout/stderr. * Fixed possible infinite recursion in Windows SEH. * Fixed possible compilation error caused by Catch's operator overloads being ambiguous in regards to user-defined templated operators. ## 1.7.0 ### Features/ Changes: * Catch now runs significantly faster for passing tests * Microbenchmark focused on Catch's overhead went from ~3.4s to ~0.7s. * Real world test using [JSON for Modern C++](https://github.com/nlohmann/json)'s test suite went from ~6m 25s to ~4m 14s. * Catch can now run specific sections within test cases. * For now the support is only basic (no wildcards or tags), for details see the [documentation](command-line.md). * Catch now supports SEH on Windows as well as signals on Linux. * After receiving a signal, Catch reports failing assertion and then passes the signal onto the previous handler. * Approx can be used to compare values against strong typedefs (available in C++11 mode only). * Strong typedefs mean types that are explicitly convertible to double. * CHECK macro no longer stops executing section if an exception happens. * Certain characters (space, tab, etc) are now pretty printed. * This means that a `char c = ' '; REQUIRE(c == '\t');` would be printed as `' ' == '\t'`, instead of ` == 9`. ### Fixes: * Text formatting no longer attempts to access out-of-bounds characters under certain conditions. * THROW family of assertions no longer trigger `-Wunused-value` on expressions containing explicit cast. * Breaking into debugger under OS X works again and no longer required `DEBUG` to be defined. * Compilation no longer breaks under certain compiler if a lambda is used inside assertion macro. ### Other: * Catch's CMakeLists now defines install command. * Catch's CMakeLists now generates projects with warnings enabled. ## 1.6.1 ### Features/ Changes: * Catch now supports breaking into debugger on Linux ### Fixes: * Generators no longer leak memory (generators are still unsupported in general) * JUnit reporter now reports UTC timestamps, instead of "tbd" * `CHECK_THAT` macro is now properly defined as `CATCH_CHECK_THAT` when using `CATCH_` prefixed macros ### Other: * Types with overloaded `&&` operator are no longer evaluated twice when used in an assertion macro. * The use of `__COUNTER__` is supressed when Catch is parsed by CLion * This change is not active when compiling a binary * Approval tests can now be run on Windows * CMake will now warn if a file is present in the `include` folder but not is not enumerated as part of the project * Catch now defines `NOMINMAX` and `WIN32_LEAN_AND_MEAN` before including `windows.h` * This can be disabled if needed, see [documentation](configuration.md) for details. ## 1.6.0 ### Cmake/ projects: * Moved CMakeLists.txt to root, made it friendlier for CLion and generating XCode and VS projects, and removed the manually maintained XCode and VS projects. ### Features/ Changes: * Approx now supports `>=` and `<=` * Can now use `\` to escape chars in test names on command line * Standardize C++11 feature toggles ### Fixes: * Blue shell colour * Missing argument to `CATCH_CHECK_THROWS` * Don't encode extended ASCII in XML * use `std::shuffle` on more compilers (fixes deprecation warning/error) * Use `__COUNTER__` more consistently (where available) ### Other: * Tweaks and changes to scripts - particularly for Approval test - to make them more portable # Older versions Release notes were not maintained prior to v1.6.0, but you should be able to work them out from the Git history --- [Home](Readme.md) catch-1.12.1/docs/release-process.md000066400000000000000000000070531325474075300172430ustar00rootroot00000000000000# 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. ## Neccessary 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. ### Approval testing Catch's releases are primarily validated against output from previous release, stored in `projects/SelfTest/Baselines`. To validate current sources, build the SelfTest binary and pass it to the `approvalTests.py` script: `approvalTests.py `. There should be no differences, as Approval tests should be updated when changes to Catch are made, but if there are, then they need to be manually reviewed and either approved (using `approve.py`) or Catch requires other fixes. ### Incrementing version number Catch uses a variant of [semantic versioning](http://semver.org/), with breaking API changes (and thus major version increments) being very rare. Thus, the release will usually increment the patch version, when it only contains couple of bugfixes, or minor version, when it contains new functionality, or larger changes in implementation of current functionality. After deciding which part of version number should be incremented, you can use one of the `*Release.py` scripts to perform the required changes to Catch. ### Generate updated single-include header After updating version number, regenerate single-include header using `generateSingleHeader.py`. ### Release notes Once a release is ready, release notes need to be written. They should summarize changes done since last release. For rough idea of expected notes see previous releases. Once written, release notes should be placed in `docs/release-notes.md`. ### Commit and push update to GitHub After version number is incremented, single-include header is regenerated and release notes are updated, changes should be commited and pushed to GitHub. ### Release on GitHub After pushing changes to GitHub, GitHub release *needs* to be created. Tag version and release title should be same as the new version, description should contain the release notes for the current release. Single header version of `catch.hpp` *needs* to be attached as a binary, as that is where the official download link links to. Preferably it should use linux line endings. ## Optional steps The following steps are optional, and do not have to be performed when releasing new version of Catch. However, they are *should* happen, but they can happen the next day without losing anything significant. ### 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. 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: ``` GitHub Catch vcpkg ``` ### Wandbox update Recently we also included a link to wandbox with preloaded Catch on the main page. Strictly speaking it is unneccessary to update this after every release, Catch usually does not change that much between versions, but it should be kept up to date anyway. catch-1.12.1/docs/reporters.md000066400000000000000000000054031325474075300161710ustar00rootroot00000000000000# Reporters Catch has a modular reporting system and comes bundled with a handful of useful reporters built in. You can also write your own reporters. ## Using different reporters The reporter to use can easily be controlled from the command line. To specify a reporter use [`-r` or `--reporter`](command-line.md#choosing-a-reporter-to-use), followed by the name of the reporter, e.g.: ``` -r xml ``` If you don't specify a reporter then the console reporter is used by default. There are four reporters built in to the single include: * `console` writes as lines of text, formatted to a typical terminal width, with colours if a capable terminal is detected. * `compact` similar to `console` but optimised for minimal output - each entry on one line * `junit` writes xml that corresponds to Ant's [junitreport](http://help.catchsoftware.com/display/ET/JUnit+Format) target. Useful for build systems that understand Junit. If you are using Jenkins with Catch 1.x, you can improve quality of output by applying changes in [#923](https://github.com/philsquared/Catch/pull/923). Because of the way the junit format is structured the run must complete before anything is written. * `xml` writes an xml format tailored to Catch. Unlike `junit` this is a streaming format so results are delivered progressively. There are a few additional reporters, for specific build systems, in the Catch repository (in `include\reporters`) which you can `#include` in your project if you would like to make use of them. Do this in one source file - typically the same one you have `CATCH_CONFIG_MAIN` or `CATCH_CONFIG_RUNNER`. * `teamcity` writes the native, streaming, format that [TeamCity](https://www.jetbrains.com/teamcity/) understands. Use this when building as part of a TeamCity build to see results as they happen. * `tap` writes in the TAP ([Test Anything Protocol](https://en.wikipedia.org/wiki/Test_Anything_Protocol)) format. * `automake` writes in a format that correspond to [automake .trs](https://www.gnu.org/software/automake/manual/html_node/Log-files-generation-and-test-results-recording.html) files You see what reporters are available from the command line by running with `--list-reporters`. By default all these reports are written to stdout, but can be redirected to a file with [`-o` or `--out`](command-line.md#sending-output-to-a-file) ## Writing your own reporter You can write your own custom reporter and register it with Catch. At time of writing the interface is subject to some changes so is not, yet, documented here. If you are determined you shouldn't have too much trouble working it out from the existing implementations - but do keep in mind upcoming changes (these will be minor, simplifying, changes such as not needing to forward calls to the base class). --- [Home](Readme.md)catch-1.12.1/docs/slow-compiles.md000066400000000000000000000075701325474075300167500ustar00rootroot00000000000000# Why do my tests take so long to compile? Several people have reported that test code written with Catch takes much longer to compile than they would expect. Why is that? Catch is implemented entirely in headers. There is a little overhead due to this - but not as much as you might think - and you can minimise it simply by organising your test code as follows: ## Short answer Exactly one source file must ```#define``` either ```CATCH_CONFIG_MAIN``` or ```CATCH_CONFIG_RUNNER``` before ```#include```-ing Catch. In this file *do not write any test cases*! In most cases that means this file will just contain two lines (the ```#define``` and the ```#include```). ## Long answer Usually C++ code is split between a header file, containing declarations and prototypes, and an implementation file (.cpp) containing the definition, or implementation, code. Each implementation file, along with all the headers that it includes (and which those headers include, etc), is expanded into a single entity called a translation unit - which is then passed to the compiler and compiled down to an object file. But functions and methods can also be written inline in header files. The downside to this is that these definitions will then be compiled in *every* translation unit that includes the header. Because Catch is implemented *entirely* in headers you might think that the whole of Catch must be compiled into every translation unit that uses it! Actually it's not quite as bad as that. Catch mitigates this situation by effectively maintaining the traditional separation between the implementation code and declarations. Internally the implementation code is protected by ```#ifdef```s and is conditionally compiled into only one translation unit. This translation unit is that one that ```#define```s ```CATCH_CONFIG_MAIN``` or ```CATCH_CONFIG_RUNNER```. Let's call this the main source file. As a result the main source file *does* compile the whole of Catch every time! So it makes sense to dedicate this file to *only* ```#define```-ing the identifier and ```#include```-ing Catch (and implementing the runner code, if you're doing that). Keep all your test cases in other files. This way you won't pay the recompilation cost for the whole of Catch ## Practical example Assume you have the `Factorial` function from the [tutorial](tutorial.md) in `factorial.cpp` (with forward declaration in `factorial.h`) and want to test it and keep the compile times down when adding new tests. Then you should have 2 files, `tests-main.cpp` and `tests-factorial.cpp`: ```cpp // tests-main.cpp #define CATCH_CONFIG_MAIN #include "catch.hpp" ``` ```cpp // tests-factorial.cpp #include "catch.hpp" #include "factorial.h" TEST_CASE( "Factorials are computed", "[factorial]" ) { REQUIRE( Factorial(1) == 1 ); REQUIRE( Factorial(2) == 2 ); REQUIRE( Factorial(3) == 6 ); REQUIRE( Factorial(10) == 3628800 ); } ``` After compiling `tests-main.cpp` once, it is enough to link it with separately compiled `tests-factorial.cpp`. This means that adding more tests to `tests-factorial.cpp`, will not result in recompiling Catch's main and the resulting compilation times will decrease substantially. ``` $ g++ tests-main.cpp -c $ g++ tests-main.o tests-factorial.cpp -o tests && ./tests -r compact Passed 1 test case with 4 assertions. ``` Now, the next time we change the file `tests-factorial.cpp` (say we add `REQUIRE( Factorial(0) == 1)`), it is enough to recompile the tests instead of recompiling main as well: ``` $ g++ tests-main.o tests-factorial.cpp -o tests && ./tests -r compact tests-factorial.cpp:11: failed: Factorial(0) == 1 for: 0 == 1 Failed 1 test case, failed 1 assertion. ``` ## Other possible solutions You can also opt to sacrifice some features in order to speed-up Catch's compilation times. For details see the [documentation on Catch's compile-time configuration](configuration.md#other-toggles). --- [Home](Readme.md)catch-1.12.1/docs/test-cases-and-sections.md000066400000000000000000000135401325474075300206050ustar00rootroot00000000000000# Test cases and sections While Catch fully supports the traditional, xUnit, style of class-based fixtures containing test case methods this is not the preferred style. Instead Catch provides a powerful mechanism for nesting test case sections within a test case. For a more detailed discussion see the [tutorial](tutorial.md#test-cases-and-sections). Test cases and sections are very easy to use in practice: * **TEST_CASE(** _test name_ \[, _tags_ \] **)** * **SECTION(** _section name_ **)** _test name_ and _section name_ are free form, quoted, strings. The optional _tags_ argument is a quoted string containing one or more tags enclosed in square brackets. Tags are discussed below. Test names must be unique within the Catch executable. For examples see the [Tutorial](tutorial.md) ## Tags Tags allow an arbitrary number of additional strings to be associated with a test case. Test cases can be selected (for running, or just for listing) by tag - or even by an expression that combines several tags. At their most basic level they provide a simple way to group several related tests together. As an example - given the following test cases: TEST_CASE( "A", "[widget]" ) { /* ... */ } TEST_CASE( "B", "[widget]" ) { /* ... */ } TEST_CASE( "C", "[gadget]" ) { /* ... */ } TEST_CASE( "D", "[widget][gadget]" ) { /* ... */ } The tag expression, ```"[widget]"``` selects A, B & D. ```"[gadget]"``` selects C & D. ```"[widget][gadget]"``` selects just D and ```"[widget],[gadget]"``` selects all four test cases. For more detail on command line selection see [the command line docs](command-line.md#specifying-which-tests-to-run) Tag names are not case sensitive and can contain any ASCII characters. This means that tags `[tag with spaces]` and `[I said "good day"]` are both allowed tags and can be filtered on. Escapes are not supported however and `[\]]` is not a valid tag. ### Special Tags All tag names beginning with non-alphanumeric characters are reserved by Catch. Catch defines a number of "special" tags, which have meaning to the test runner itself. These special tags all begin with a symbol character. Following is a list of currently defined special tags and their meanings. * `[!hide]` or `[.]` (or, for legacy reasons, `[hide]`) - causes test cases to be skipped from the default list (i.e. when no test cases have been explicitly selected through tag expressions or name wildcards). The hide tag is often combined with another, user, tag (for example `[.][integration]` - so all integration tests are excluded from the default run but can be run by passing `[integration]` on the command line). As a short-cut you can combine these by simply prefixing your user tag with a `.` - e.g. `[.integration]`. Because the hide tag has evolved to have several forms, all forms are added as tags if you use one of them. * `[!throws]` - lets Catch know that this test is likely to throw an exception even if successful. This causes the test to be excluded when running with `-e` or `--nothrow`. * `[!mayfail]` - doesn't fail the test if any given assertion fails (but still reports it). This can be useful to flag a work-in-progress, or a known issue that you don't want to immediately fix but still want to track in your tests. * `[!shouldfail]` - like `[!mayfail]` but *fails* the test if it *passes*. This can be useful if you want to be notified of accidental, or third-party, fixes. * `[!nonportable]` - Indicates that behaviour may vary between platforms or compilers. * `[#]` - running with `-#` or `--filenames-as-tags` causes Catch to add the filename, prefixed with `#` (and with any extension stripped), as a tag to all contained tests, e.g. tests in testfile.cpp would all be tagged `[#testfile]`. * `[@]` - tag aliases all begin with `@` (see below). ## Tag aliases Between tag expressions and wildcarded test names (as well as combinations of the two) quite complex patterns can be constructed to direct which test cases are run. If a complex pattern is used often it is convenient to be able to create an alias for the expression. This can be done, in code, using the following form: CATCH_REGISTER_TAG_ALIAS( , ) Aliases must begin with the `@` character. An example of a tag alias is: CATCH_REGISTER_TAG_ALIAS( "[@nhf]", "[failing]~[.]" ) Now when `[@nhf]` is used on the command line this matches all tests that are tagged `[failing]`, but which are not also hidden. ## BDD-style test cases In addition to Catch's take on the classic style of test cases, Catch supports an alternative syntax that allow tests to be written as "executable specifications" (one of the early goals of [Behaviour Driven Development](http://dannorth.net/introducing-bdd/)). This set of macros map on to ```TEST_CASE```s and ```SECTION```s, with a little internal support to make them smoother to work with. * **SCENARIO(** _scenario name_ \[, _tags_ \] **)** This macro maps onto ```TEST_CASE``` and works in the same way, except that the test case name will be prefixed by "Scenario: " * **GIVEN(** _something_ **)** * **WHEN(** _something_ **)** * **THEN(** _something_ **)** These macros map onto ```SECTION```s except that the section names are the _something_s prefixed by "given: ", "when: " or "then: " respectively. * **AND_WHEN(** _something_ **)** * **AND_THEN(** _something_ **)** Similar to ```WHEN``` and ```THEN``` except that the prefixes start with "and ". These are used to chain ```WHEN```s and ```THEN```s together. When any of these macros are used the console reporter recognises them and formats the test case header such that the Givens, Whens and Thens are aligned to aid readability. Other than the additional prefixes and the formatting in the console reporter these macros behave exactly as ```TEST_CASE```s and ```SECTION```s. As such there is nothing enforcing the correct sequencing of these macros - that's up to the programmer! --- [Home](Readme.md) catch-1.12.1/docs/test-fixtures.md000066400000000000000000000024511325474075300167720ustar00rootroot00000000000000Although Catch allows you to group tests together as sections within a test case, it can still be convenient, sometimes, to group them using a more traditional test fixture. Catch fully supports this too. You define the test fixture as a simple structure: ```c++ class UniqueTestsFixture { private: static int uniqueID; protected: DBConnection conn; public: UniqueTestsFixture() : conn(DBConnection::createConnection("myDB")) { } protected: int getID() { return ++uniqueID; } }; int UniqueTestsFixture::uniqueID = 0; TEST_CASE_METHOD(UniqueTestsFixture, "Create Employee/No Name", "[create]") { REQUIRE_THROWS(conn.executeSQL("INSERT INTO employee (id, name) VALUES (?, ?)", getID(), "")); } TEST_CASE_METHOD(UniqueTestsFixture, "Create Employee/Normal", "[create]") { REQUIRE(conn.executeSQL("INSERT INTO employee (id, name) VALUES (?, ?)", getID(), "Joe Bloggs")); } ``` The two test cases here will create uniquely-named derived classes of UniqueTestsFixture and thus can access the `getID()` protected method and `conn` member variables. This ensures that both the test cases are able to create a DBConnection using the same method (DRY principle) and that any ID's created are unique such that the order that tests are executed does not matter. --- [Home](Readme.md) catch-1.12.1/docs/tostring.md000066400000000000000000000055521325474075300160220ustar00rootroot00000000000000# String conversions Catch needs to be able to convert types you use in assertions and logging expressions into strings (for logging and reporting purposes). Most built-in or std types are supported out of the box but there are three ways that you can tell Catch how to convert your own types (or other, third-party types) into strings. ## operator << overload for std::ostream This is the standard way of providing string conversions in C++ - and the chances are you may already provide this for your own purposes. If you're not familiar with this idiom it involves writing a free function of the form: ``` std::ostream& operator << ( std::ostream& os, T const& value ) { os << convertMyTypeToString( value ); return os; } ``` (where ```T``` is your type and ```convertMyTypeToString``` is where you'll write whatever code is necessary to make your type printable - it doesn't have to be in another function). You should put this function in the same namespace as your type and it has to be declared before including Catch's header. ## Catch::toString overload If you don't want to provide an ```operator <<``` overload, or you want to convert your type differently for testing purposes, you can provide an overload for ```Catch::toString()``` for your type. ``` namespace Catch { std::string toString( T const& value ) { return convertMyTypeToString( value ); } } ``` Again ```T``` is your type and ```convertMyTypeToString``` is where you'll write whatever code is necessary to make your type printable. Note that the function must be in the Catch namespace, which itself must be in the global namespace and must be declared _before_ Catch's header is included. **Please note that overloading `Catch::toString` is currently considered legacy and will not be supported in the next major version of Catch.** ## Catch::StringMaker specialisation Another way of telling Catch how to convert a type to string is specialising `Catch::StringMaker` template. This allows you to have separate way of stringifying types for Catch, than you have for writing it to a stream and also doesn't require you to declare it before including Catch's header. ``` namespace Catch { template<> struct StringMaker { static std::string convert( T const& value ) { return convertMyTypeToString( value ); } }; } ``` ## Exceptions By default all exceptions deriving from `std::exception` will be translated to strings by calling the `what()` method. For exception types that do not derive from `std::exception` - or if `what()` does not return a suitable string - use `CATCH_TRANSLATE_EXCEPTION`. This defines a function that takes your exception type, by reference, and returns a string. It can appear anywhere in the code - it doesn't have to be in the same translation unit. For example: ``` CATCH_TRANSLATE_EXCEPTION( MyType& ex ) { return ex.message(); } ``` --- [Home](Readme.md) catch-1.12.1/docs/tutorial.md000066400000000000000000000323651325474075300160160ustar00rootroot00000000000000# Getting Catch The simplest way to get Catch is to download the latest [single header version](https://raw.githubusercontent.com/philsquared/Catch/master/single_include/catch.hpp). The single header is generated by merging a set of individual headers but it is still just normal source code in a header file. The full source for Catch, including test projects, documentation, and other things, is hosted on GitHub. [http://catch-lib.net](http://catch-lib.net) will redirect you there. ## Where to put it? Catch is header only. All you need to do is drop the file(s) somewhere reachable from your project - either in some central location you can set your header search path to find, or directly into your project tree itself! This is a particularly good option for other Open-Source projects that want to use Catch for their test suite. See [this blog entry for more on that](http://www.levelofindirection.com/journal/2011/5/27/unit-testing-in-c-and-objective-c-just-got-ridiculously-easi.html). The rest of this tutorial will assume that the Catch single-include header (or the include folder) is available unqualified - but you may need to prefix it with a folder name if necessary. # Writing tests Let's start with a really simple example. Say you have written a function to calculate factorials and now you want to test it (let's leave aside TDD for now). ```c++ unsigned int Factorial( unsigned int number ) { return number <= 1 ? number : Factorial(number-1)*number; } ``` To keep things simple we'll put everything in a single file (see later for more on how to structure your test files) ```c++ #define CATCH_CONFIG_MAIN // This tells Catch to provide a main() - only do this in one cpp file #include "catch.hpp" unsigned int Factorial( unsigned int number ) { return number <= 1 ? number : Factorial(number-1)*number; } TEST_CASE( "Factorials are computed", "[factorial]" ) { REQUIRE( Factorial(1) == 1 ); REQUIRE( Factorial(2) == 2 ); REQUIRE( Factorial(3) == 6 ); REQUIRE( Factorial(10) == 3628800 ); } ``` This will compile to a complete executable which responds to [command line arguments](command-line.md). If you just run it with no arguments it will execute all test cases (in this case there is just one), report any failures, report a summary of how many tests passed and failed and return the number of failed tests (useful for if you just want a yes/ no answer to: "did it work"). If you run this as written it will pass. Everything is good. Right? Well, there is still a bug here. In fact the first version of this tutorial I posted here genuinely had the bug in! So it's not completely contrived (thanks to Daryle Walker (```@CTMacUser```) for pointing this out). What is the bug? Well what is the factorial of zero? [The factorial of zero is one](http://mathforum.org/library/drmath/view/57128.html) - which is just one of those things you have to know (and remember!). Let's add that to the test case: ```c++ TEST_CASE( "Factorials are computed", "[factorial]" ) { REQUIRE( Factorial(0) == 1 ); REQUIRE( Factorial(1) == 1 ); REQUIRE( Factorial(2) == 2 ); REQUIRE( Factorial(3) == 6 ); REQUIRE( Factorial(10) == 3628800 ); } ``` Now we get a failure - something like: ``` Example.cpp:9: FAILED: REQUIRE( Factorial(0) == 1 ) with expansion: 0 == 1 ``` Note that we get the actual return value of Factorial(0) printed for us (0) - even though we used a natural expression with the == operator. That lets us immediately see what the problem is. Let's change the factorial function to: ```c++ unsigned int Factorial( unsigned int number ) { return number > 1 ? Factorial(number-1)*number : 1; } ``` Now all the tests pass. Of course there are still more issues to deal with. For example we'll hit problems when the return value starts to exceed the range of an unsigned int. With factorials that can happen quite quickly. You might want to add tests for such cases and decide how to handle them. We'll stop short of doing that here. ## What did we do here? Although this was a simple test it's been enough to demonstrate a few things about how Catch is used. Let's take moment to consider those before we move on. 1. All we did was ```#define``` one identifier and ```#include``` one header and we got everything - even an implementation of ```main()``` that will [respond to command line arguments](command-line.md). You can only use that ```#define``` in one implementation file, for (hopefully) obvious reasons. Once you have more than one file with unit tests in you'll just ```#include "catch.hpp"``` and go. Usually it's a good idea to have a dedicated implementation file that just has ```#define CATCH_CONFIG_MAIN``` and ```#include "catch.hpp"```. You can also provide your own implementation of main and drive Catch yourself (see [Supplying-your-own-main()](own-main.md)). 2. We introduce test cases with the ```TEST_CASE``` macro. This macro takes one or two arguments - a free form test name and, optionally, one or more tags (for more see Test cases and Sections, ). The test name must be unique. You can run sets of tests by specifying a wildcarded test name or a tag expression. See the [command line docs](command-line.md) for more information on running tests. 3. The name and tags arguments are just strings. We haven't had to declare a function or method - or explicitly register the test case anywhere. Behind the scenes a function with a generated name is defined for you, and automatically registered using static registry classes. By abstracting the function name away we can name our tests without the constraints of identifier names. 4. We write our individual test assertions using the ```REQUIRE``` macro. Rather than a separate macro for each type of condition we express the condition naturally using C/C++ syntax. Behind the scenes a simple set of expression templates captures the left-hand-side and right-hand-side of the expression so we can display the values in our test report. As we'll see later there _are_ other assertion macros - but because of this technique the number of them is drastically reduced. ## Test cases and sections Most test frameworks have a class-based fixture mechanism. That is, test cases map to methods on a class and common setup and teardown can be performed in ```setup()``` and ```teardown()``` methods (or constructor/ destructor in languages, like C++, that support deterministic destruction). While Catch fully supports this way of working there are a few problems with the approach. In particular the way your code must be split up, and the blunt granularity of it, may cause problems. You can only have one setup/ teardown pair across a set of methods, but sometimes you want slightly different setup in each method, or you may even want several levels of setup (a concept which we will clarify later on in this tutorial). It was problems like these that led James Newkirk, who led the team that built NUnit, to start again from scratch and build xUnit). Catch takes a different approach (to both NUnit and xUnit) that is a more natural fit for C++ and the C family of languages. This is best explained through an example: ```c++ TEST_CASE( "vectors can be sized and resized", "[vector]" ) { std::vector v( 5 ); REQUIRE( v.size() == 5 ); REQUIRE( v.capacity() >= 5 ); SECTION( "resizing bigger changes size and capacity" ) { v.resize( 10 ); REQUIRE( v.size() == 10 ); REQUIRE( v.capacity() >= 10 ); } SECTION( "resizing smaller changes size but not capacity" ) { v.resize( 0 ); REQUIRE( v.size() == 0 ); REQUIRE( v.capacity() >= 5 ); } SECTION( "reserving bigger changes capacity but not size" ) { v.reserve( 10 ); REQUIRE( v.size() == 5 ); REQUIRE( v.capacity() >= 10 ); } SECTION( "reserving smaller does not change size or capacity" ) { v.reserve( 0 ); REQUIRE( v.size() == 5 ); REQUIRE( v.capacity() >= 5 ); } } ``` For each ```SECTION``` the ```TEST_CASE``` is executed from the start - so as we enter each section we know that size is 5 and capacity is at least 5. We enforced those requirements with the ```REQUIRE```s at the top level so we can be confident in them. This works because the ```SECTION``` macro contains an if statement that calls back into Catch to see if the section should be executed. One leaf section is executed on each run through a ```TEST_CASE```. The other sections are skipped. Next time through the next section is executed, and so on until no new sections are encountered. So far so good - this is already an improvement on the setup/teardown approach because now we see our setup code inline and use the stack. The power of sections really shows, however, when we need to execute a sequence of, checked, operations. Continuing the vector example, we might want to verify that attempting to reserve a capacity smaller than the current capacity of the vector changes nothing. We can do that, naturally, like so: ```c++ SECTION( "reserving bigger changes capacity but not size" ) { v.reserve( 10 ); REQUIRE( v.size() == 5 ); REQUIRE( v.capacity() >= 10 ); SECTION( "reserving smaller again does not change capacity" ) { v.reserve( 7 ); REQUIRE( v.capacity() >= 10 ); } } ``` Sections can be nested to an arbitrary depth (limited only by your stack size). Each leaf section (i.e. a section that contains no nested sections) will be executed exactly once, on a separate path of execution from any other leaf section (so no leaf section can interfere with another). A failure in a parent section will prevent nested sections from running - but then that's the idea. ## BDD-Style If you name your test cases and sections appropriately you can achieve a BDD-style specification structure. This became such a useful way of working that first class support has been added to Catch. Scenarios can be specified using ```SCENARIO```, ```GIVEN```, ```WHEN``` and ```THEN``` macros, which map on to ```TEST_CASE```s and ```SECTION```s, respectively. For more details see [Test cases and sections](test-cases-and-sections.md). The vector example can be adjusted to use these macros like so: ```c++ SCENARIO( "vectors can be sized and resized", "[vector]" ) { GIVEN( "A vector with some items" ) { std::vector v( 5 ); REQUIRE( v.size() == 5 ); REQUIRE( v.capacity() >= 5 ); WHEN( "the size is increased" ) { v.resize( 10 ); THEN( "the size and capacity change" ) { REQUIRE( v.size() == 10 ); REQUIRE( v.capacity() >= 10 ); } } WHEN( "the size is reduced" ) { v.resize( 0 ); THEN( "the size changes but not capacity" ) { REQUIRE( v.size() == 0 ); REQUIRE( v.capacity() >= 5 ); } } WHEN( "more capacity is reserved" ) { v.reserve( 10 ); THEN( "the capacity changes but not the size" ) { REQUIRE( v.size() == 5 ); REQUIRE( v.capacity() >= 10 ); } } WHEN( "less capacity is reserved" ) { v.reserve( 0 ); THEN( "neither size nor capacity are changed" ) { REQUIRE( v.size() == 5 ); REQUIRE( v.capacity() >= 5 ); } } } } ``` Conveniently, these tests will be reported as follows when run: ``` Scenario: vectors can be sized and resized Given: A vector with some items When: more capacity is reserved Then: the capacity changes but not the size ``` ## Scaling up To keep the tutorial simple we put all our code in a single file. This is fine to get started - and makes jumping into Catch even quicker and easier. As you write more real-world tests, though, this is not really the best approach. The requirement is that the following block of code ([or equivalent](own-main.md)): ```c++ #define CATCH_CONFIG_MAIN #include "catch.hpp" ``` appears in _exactly one_ source file. Use as many additional cpp files (or whatever you call your implementation files) as you need for your tests, partitioned however makes most sense for your way of working. Each additional file need only ```#include "catch.hpp"``` - do not repeat the ```#define```! In fact it is usually a good idea to put the block with the ```#define``` [in its own source file](slow-compiles.md). Do not write your tests in header files! ## Next steps This has been a brief introduction to get you up and running with Catch, and to point out some of the key differences between Catch and other frameworks you may already be familiar with. This will get you going quite far already and you are now in a position to dive in and write some tests. Of course there is more to learn - most of which you should be able to page-fault in as you go. Please see the ever-growing [Reference section](Readme.md) for what's available. --- [Home](Readme.md) catch-1.12.1/docs/why-catch.md000066400000000000000000000056571325474075300160460ustar00rootroot00000000000000# Why do we need yet another C++ test framework? Good question. For C++ there are quite a number of established frameworks, including (but not limited to), [CppUnit](http://sourceforge.net/apps/mediawiki/cppunit/index.php?title=Main_Page), [Google Test](http://code.google.com/p/googletest/), [Boost.Test](http://www.boost.org/doc/libs/1_49_0/libs/test/doc/html/index.html), [Aeryn](https://launchpad.net/aeryn), [Cute](http://r2.ifs.hsr.ch/cute), [Fructose](http://fructose.sourceforge.net/) and [many, many more](http://en.wikipedia.org/wiki/List_of_unit_testing_frameworks#C.2B.2B). Even for Objective-C there are a few, including OCUnit - which now comes bundled with XCode. So what does Catch bring to the party that differentiates it from these? Apart from a Catchy name, of course. ## Key Features * Really easy to get started. Just download catch.hpp, #include it and you're away. * No external dependencies. As long as you can compile C++98 and have a C++ standard library available. * Write test cases as, self-registering, functions or methods. * Divide test cases into sections, each of which is run in isolation (eliminates the need for fixtures!) * Use BDD-style Given-When-Then sections as well as traditional unit test cases. * Only one core assertion macro for comparisons. Standard C/C++ operators are used for the comparison - yet the full expression is decomposed and lhs and rhs values are logged. ## Other core features * Tests are named using free-form strings - no more couching names in legal identifiers. * Tests can be tagged for easily running ad-hoc groups of tests. * Failures can (optionally) break into the debugger on Windows and Mac. * Output is through modular reporter objects. Basic textual and XML reporters are included. Custom reporters can easily be added. * JUnit xml output is supported for integration with third-party tools, such as CI servers. * A default main() function is provided (in a header), but you can supply your own for complete control (e.g. integration into your own test runner GUI). * A command line parser is provided and can still be used if you choose to provided your own main() function. * Catch can test itself. * Alternative assertion macro(s) report failures but don't abort the test case * Floating point tolerance comparisons are built in using an expressive Approx() syntax. * Internal and friendly macros are isolated so name clashes can be managed * Support for Matchers (early stages) ## Objective-C-specific features * Automatically detects if you are using it from an Objective-C project * Works with and without ARC with no additional configuration * Implement test fixtures using Obj-C classes too (like OCUnit) * Additional built in matchers that work with Obj-C types (e.g. string matchers) ## Who else is using Catch? See the list of [open source projects using Catch](opensource-users.md). See the [tutorial](tutorial.md) to get more of a taste of using CATCH in practice --- [Home](Readme.md)catch-1.12.1/include/000077500000000000000000000000001325474075300143135ustar00rootroot00000000000000catch-1.12.1/include/catch.hpp000066400000000000000000000365271325474075300161230ustar00rootroot00000000000000/* * Created by Phil on 22/10/2010. * Copyright 2010 Two Blue Cubes Ltd * * Distributed under the Boost Software License, Version 1.0. (See accompanying * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) */ #ifndef TWOBLUECUBES_CATCH_HPP_INCLUDED #define TWOBLUECUBES_CATCH_HPP_INCLUDED #ifdef __clang__ # pragma clang system_header #elif defined __GNUC__ # pragma GCC system_header #endif #include "internal/catch_suppress_warnings.h" #if defined(CATCH_CONFIG_MAIN) || defined(CATCH_CONFIG_RUNNER) # define CATCH_IMPL #endif #ifdef CATCH_IMPL # ifndef CLARA_CONFIG_MAIN # define CLARA_CONFIG_MAIN_NOT_DEFINED # define CLARA_CONFIG_MAIN # endif #endif #include "internal/catch_notimplemented_exception.h" #include "internal/catch_context.h" #include "internal/catch_test_registry.hpp" #include "internal/catch_capture.hpp" #include "internal/catch_section.h" #include "internal/catch_generators.hpp" #include "internal/catch_interfaces_exception.h" #include "internal/catch_approx.hpp" #include "internal/catch_matchers_string.h" #include "internal/catch_matchers_vector.h" #include "internal/catch_compiler_capabilities.h" #include "internal/catch_interfaces_tag_alias_registry.h" // These files are included here so the single_include script doesn't put them // in the conditionally compiled sections #include "internal/catch_test_case_info.h" #include "internal/catch_interfaces_runner.h" #ifdef __OBJC__ #include "internal/catch_objc.hpp" #endif #ifdef CATCH_IMPL // !TBD: Move the leak detector code into a separate header #ifdef CATCH_CONFIG_WINDOWS_CRTDBG #include class LeakDetector { public: LeakDetector() { int flag = _CrtSetDbgFlag(_CRTDBG_REPORT_FLAG); flag |= _CRTDBG_LEAK_CHECK_DF; flag |= _CRTDBG_ALLOC_MEM_DF; _CrtSetDbgFlag(flag); _CrtSetReportMode(_CRT_WARN, _CRTDBG_MODE_FILE | _CRTDBG_MODE_DEBUG); _CrtSetReportFile(_CRT_WARN, _CRTDBG_FILE_STDERR); // Change this to leaking allocation's number to break there _CrtSetBreakAlloc(-1); } }; #else class LeakDetector {}; #endif LeakDetector leakDetector; #include "internal/catch_impl.hpp" #endif #ifdef CATCH_CONFIG_MAIN #include "internal/catch_default_main.hpp" #endif #ifdef CLARA_CONFIG_MAIN_NOT_DEFINED # undef CLARA_CONFIG_MAIN #endif ////// // If this config identifier is defined then all CATCH macros are prefixed with CATCH_ #ifdef CATCH_CONFIG_PREFIX_ALL #if defined(CATCH_CONFIG_FAST_COMPILE) #define CATCH_REQUIRE( expr ) INTERNAL_CATCH_TEST_NO_TRY( "CATCH_REQUIRE", Catch::ResultDisposition::Normal, expr ) #define CATCH_REQUIRE_FALSE( expr ) INTERNAL_CATCH_TEST_NO_TRY( "CATCH_REQUIRE_FALSE", Catch::ResultDisposition::Normal | Catch::ResultDisposition::FalseTest, expr ) #else #define CATCH_REQUIRE( expr ) INTERNAL_CATCH_TEST( "CATCH_REQUIRE", Catch::ResultDisposition::Normal, expr ) #define CATCH_REQUIRE_FALSE( expr ) INTERNAL_CATCH_TEST( "CATCH_REQUIRE_FALSE", Catch::ResultDisposition::Normal | Catch::ResultDisposition::FalseTest, expr ) #endif #define CATCH_REQUIRE_THROWS( expr ) INTERNAL_CATCH_THROWS( "CATCH_REQUIRE_THROWS", Catch::ResultDisposition::Normal, "", expr ) #define CATCH_REQUIRE_THROWS_AS( expr, exceptionType ) INTERNAL_CATCH_THROWS_AS( "CATCH_REQUIRE_THROWS_AS", exceptionType, Catch::ResultDisposition::Normal, expr ) #define CATCH_REQUIRE_THROWS_WITH( expr, matcher ) INTERNAL_CATCH_THROWS( "CATCH_REQUIRE_THROWS_WITH", Catch::ResultDisposition::Normal, matcher, expr ) #define CATCH_REQUIRE_NOTHROW( expr ) INTERNAL_CATCH_NO_THROW( "CATCH_REQUIRE_NOTHROW", Catch::ResultDisposition::Normal, expr ) #define CATCH_CHECK( expr ) INTERNAL_CATCH_TEST( "CATCH_CHECK", Catch::ResultDisposition::ContinueOnFailure, expr ) #define CATCH_CHECK_FALSE( expr ) INTERNAL_CATCH_TEST( "CATCH_CHECK_FALSE", Catch::ResultDisposition::ContinueOnFailure | Catch::ResultDisposition::FalseTest, expr ) #define CATCH_CHECKED_IF( expr ) INTERNAL_CATCH_IF( "CATCH_CHECKED_IF", Catch::ResultDisposition::ContinueOnFailure, expr ) #define CATCH_CHECKED_ELSE( expr ) INTERNAL_CATCH_ELSE( "CATCH_CHECKED_ELSE", Catch::ResultDisposition::ContinueOnFailure, expr ) #define CATCH_CHECK_NOFAIL( expr ) INTERNAL_CATCH_TEST( "CATCH_CHECK_NOFAIL", Catch::ResultDisposition::ContinueOnFailure | Catch::ResultDisposition::SuppressFail, expr ) #define CATCH_CHECK_THROWS( expr ) INTERNAL_CATCH_THROWS( "CATCH_CHECK_THROWS", Catch::ResultDisposition::ContinueOnFailure, "", expr ) #define CATCH_CHECK_THROWS_AS( expr, exceptionType ) INTERNAL_CATCH_THROWS_AS( "CATCH_CHECK_THROWS_AS", exceptionType, Catch::ResultDisposition::ContinueOnFailure, expr ) #define CATCH_CHECK_THROWS_WITH( expr, matcher ) INTERNAL_CATCH_THROWS( "CATCH_CHECK_THROWS_WITH", Catch::ResultDisposition::ContinueOnFailure, matcher, expr ) #define CATCH_CHECK_NOTHROW( expr ) INTERNAL_CATCH_NO_THROW( "CATCH_CHECK_NOTHROW", Catch::ResultDisposition::ContinueOnFailure, expr ) #define CATCH_CHECK_THAT( arg, matcher ) INTERNAL_CHECK_THAT( "CATCH_CHECK_THAT", matcher, Catch::ResultDisposition::ContinueOnFailure, arg ) #if defined(CATCH_CONFIG_FAST_COMPILE) #define CATCH_REQUIRE_THAT( arg, matcher ) INTERNAL_CHECK_THAT_NO_TRY( "CATCH_REQUIRE_THAT", matcher, Catch::ResultDisposition::Normal, arg ) #else #define CATCH_REQUIRE_THAT( arg, matcher ) INTERNAL_CHECK_THAT( "CATCH_REQUIRE_THAT", matcher, Catch::ResultDisposition::Normal, arg ) #endif #define CATCH_INFO( msg ) INTERNAL_CATCH_INFO( "CATCH_INFO", msg ) #define CATCH_WARN( msg ) INTERNAL_CATCH_MSG( "CATCH_WARN", Catch::ResultWas::Warning, Catch::ResultDisposition::ContinueOnFailure, msg ) #define CATCH_SCOPED_INFO( msg ) INTERNAL_CATCH_INFO( "CATCH_INFO", msg ) #define CATCH_CAPTURE( msg ) INTERNAL_CATCH_INFO( "CATCH_CAPTURE", #msg " := " << Catch::toString(msg) ) #define CATCH_SCOPED_CAPTURE( msg ) INTERNAL_CATCH_INFO( "CATCH_CAPTURE", #msg " := " << Catch::toString(msg) ) #ifdef CATCH_CONFIG_VARIADIC_MACROS #define CATCH_TEST_CASE( ... ) INTERNAL_CATCH_TESTCASE( __VA_ARGS__ ) #define CATCH_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TEST_CASE_METHOD( className, __VA_ARGS__ ) #define CATCH_METHOD_AS_TEST_CASE( method, ... ) INTERNAL_CATCH_METHOD_AS_TEST_CASE( method, __VA_ARGS__ ) #define CATCH_REGISTER_TEST_CASE( Function, ... ) INTERNAL_CATCH_REGISTER_TESTCASE( Function, __VA_ARGS__ ) #define CATCH_SECTION( ... ) INTERNAL_CATCH_SECTION( __VA_ARGS__ ) #define CATCH_FAIL( ... ) INTERNAL_CATCH_MSG( "CATCH_FAIL", Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::Normal, __VA_ARGS__ ) #define CATCH_FAIL_CHECK( ... ) INTERNAL_CATCH_MSG( "CATCH_FAIL_CHECK", Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ ) #define CATCH_SUCCEED( ... ) INTERNAL_CATCH_MSG( "CATCH_SUCCEED", Catch::ResultWas::Ok, Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ ) #else #define CATCH_TEST_CASE( name, description ) INTERNAL_CATCH_TESTCASE( name, description ) #define CATCH_TEST_CASE_METHOD( className, name, description ) INTERNAL_CATCH_TEST_CASE_METHOD( className, name, description ) #define CATCH_METHOD_AS_TEST_CASE( method, name, description ) INTERNAL_CATCH_METHOD_AS_TEST_CASE( method, name, description ) #define CATCH_REGISTER_TEST_CASE( function, name, description ) INTERNAL_CATCH_REGISTER_TESTCASE( function, name, description ) #define CATCH_SECTION( name, description ) INTERNAL_CATCH_SECTION( name, description ) #define CATCH_FAIL( msg ) INTERNAL_CATCH_MSG( "CATCH_FAIL", Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::Normal, msg ) #define CATCH_FAIL_CHECK( msg ) INTERNAL_CATCH_MSG( "CATCH_FAIL_CHECK", Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::ContinueOnFailure, msg ) #define CATCH_SUCCEED( msg ) INTERNAL_CATCH_MSG( "CATCH_SUCCEED", Catch::ResultWas::Ok, Catch::ResultDisposition::ContinueOnFailure, msg ) #endif #define CATCH_ANON_TEST_CASE() INTERNAL_CATCH_TESTCASE( "", "" ) #define CATCH_REGISTER_REPORTER( name, reporterType ) INTERNAL_CATCH_REGISTER_REPORTER( name, reporterType ) #define CATCH_REGISTER_LEGACY_REPORTER( name, reporterType ) INTERNAL_CATCH_REGISTER_LEGACY_REPORTER( name, reporterType ) #define CATCH_GENERATE( expr) INTERNAL_CATCH_GENERATE( expr ) // "BDD-style" convenience wrappers #ifdef CATCH_CONFIG_VARIADIC_MACROS #define CATCH_SCENARIO( ... ) CATCH_TEST_CASE( "Scenario: " __VA_ARGS__ ) #define CATCH_SCENARIO_METHOD( className, ... ) INTERNAL_CATCH_TEST_CASE_METHOD( className, "Scenario: " __VA_ARGS__ ) #else #define CATCH_SCENARIO( name, tags ) CATCH_TEST_CASE( "Scenario: " name, tags ) #define CATCH_SCENARIO_METHOD( className, name, tags ) INTERNAL_CATCH_TEST_CASE_METHOD( className, "Scenario: " name, tags ) #endif #define CATCH_GIVEN( desc ) CATCH_SECTION( std::string( "Given: ") + desc, "" ) #define CATCH_WHEN( desc ) CATCH_SECTION( std::string( " When: ") + desc, "" ) #define CATCH_AND_WHEN( desc ) CATCH_SECTION( std::string( " And: ") + desc, "" ) #define CATCH_THEN( desc ) CATCH_SECTION( std::string( " Then: ") + desc, "" ) #define CATCH_AND_THEN( desc ) CATCH_SECTION( std::string( " And: ") + desc, "" ) // If CATCH_CONFIG_PREFIX_ALL is not defined then the CATCH_ prefix is not required #else #if defined(CATCH_CONFIG_FAST_COMPILE) #define REQUIRE( expr ) INTERNAL_CATCH_TEST_NO_TRY( "REQUIRE", Catch::ResultDisposition::Normal, expr ) #define REQUIRE_FALSE( expr ) INTERNAL_CATCH_TEST_NO_TRY( "REQUIRE_FALSE", Catch::ResultDisposition::Normal | Catch::ResultDisposition::FalseTest, expr ) #else #define REQUIRE( expr ) INTERNAL_CATCH_TEST( "REQUIRE", Catch::ResultDisposition::Normal, expr ) #define REQUIRE_FALSE( expr ) INTERNAL_CATCH_TEST( "REQUIRE_FALSE", Catch::ResultDisposition::Normal | Catch::ResultDisposition::FalseTest, expr ) #endif #define REQUIRE_THROWS( expr ) INTERNAL_CATCH_THROWS( "REQUIRE_THROWS", Catch::ResultDisposition::Normal, "", expr ) #define REQUIRE_THROWS_AS( expr, exceptionType ) INTERNAL_CATCH_THROWS_AS( "REQUIRE_THROWS_AS", exceptionType, Catch::ResultDisposition::Normal, expr ) #define REQUIRE_THROWS_WITH( expr, matcher ) INTERNAL_CATCH_THROWS( "REQUIRE_THROWS_WITH", Catch::ResultDisposition::Normal, matcher, expr ) #define REQUIRE_NOTHROW( expr ) INTERNAL_CATCH_NO_THROW( "REQUIRE_NOTHROW", Catch::ResultDisposition::Normal, expr ) #define CHECK( expr ) INTERNAL_CATCH_TEST( "CHECK", Catch::ResultDisposition::ContinueOnFailure, expr ) #define CHECK_FALSE( expr ) INTERNAL_CATCH_TEST( "CHECK_FALSE", Catch::ResultDisposition::ContinueOnFailure | Catch::ResultDisposition::FalseTest, expr ) #define CHECKED_IF( expr ) INTERNAL_CATCH_IF( "CHECKED_IF", Catch::ResultDisposition::ContinueOnFailure, expr ) #define CHECKED_ELSE( expr ) INTERNAL_CATCH_ELSE( "CHECKED_ELSE", Catch::ResultDisposition::ContinueOnFailure, expr ) #define CHECK_NOFAIL( expr ) INTERNAL_CATCH_TEST( "CHECK_NOFAIL", Catch::ResultDisposition::ContinueOnFailure | Catch::ResultDisposition::SuppressFail, expr ) #define CHECK_THROWS( expr ) INTERNAL_CATCH_THROWS( "CHECK_THROWS", Catch::ResultDisposition::ContinueOnFailure, "", expr ) #define CHECK_THROWS_AS( expr, exceptionType ) INTERNAL_CATCH_THROWS_AS( "CHECK_THROWS_AS", exceptionType, Catch::ResultDisposition::ContinueOnFailure, expr ) #define CHECK_THROWS_WITH( expr, matcher ) INTERNAL_CATCH_THROWS( "CHECK_THROWS_WITH", Catch::ResultDisposition::ContinueOnFailure, matcher, expr ) #define CHECK_NOTHROW( expr ) INTERNAL_CATCH_NO_THROW( "CHECK_NOTHROW", Catch::ResultDisposition::ContinueOnFailure, expr ) #define CHECK_THAT( arg, matcher ) INTERNAL_CHECK_THAT( "CHECK_THAT", matcher, Catch::ResultDisposition::ContinueOnFailure, arg ) #if defined(CATCH_CONFIG_FAST_COMPILE) #define REQUIRE_THAT( arg, matcher ) INTERNAL_CHECK_THAT_NO_TRY( "REQUIRE_THAT", matcher, Catch::ResultDisposition::Normal, arg ) #else #define REQUIRE_THAT( arg, matcher ) INTERNAL_CHECK_THAT( "REQUIRE_THAT", matcher, Catch::ResultDisposition::Normal, arg ) #endif #define INFO( msg ) INTERNAL_CATCH_INFO( "INFO", msg ) #define WARN( msg ) INTERNAL_CATCH_MSG( "WARN", Catch::ResultWas::Warning, Catch::ResultDisposition::ContinueOnFailure, msg ) #define SCOPED_INFO( msg ) INTERNAL_CATCH_INFO( "INFO", msg ) #define CAPTURE( msg ) INTERNAL_CATCH_INFO( "CAPTURE", #msg " := " << Catch::toString(msg) ) #define SCOPED_CAPTURE( msg ) INTERNAL_CATCH_INFO( "CAPTURE", #msg " := " << Catch::toString(msg) ) #ifdef CATCH_CONFIG_VARIADIC_MACROS #define TEST_CASE( ... ) INTERNAL_CATCH_TESTCASE( __VA_ARGS__ ) #define TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TEST_CASE_METHOD( className, __VA_ARGS__ ) #define METHOD_AS_TEST_CASE( method, ... ) INTERNAL_CATCH_METHOD_AS_TEST_CASE( method, __VA_ARGS__ ) #define REGISTER_TEST_CASE( Function, ... ) INTERNAL_CATCH_REGISTER_TESTCASE( Function, __VA_ARGS__ ) #define SECTION( ... ) INTERNAL_CATCH_SECTION( __VA_ARGS__ ) #define FAIL( ... ) INTERNAL_CATCH_MSG( "FAIL", Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::Normal, __VA_ARGS__ ) #define FAIL_CHECK( ... ) INTERNAL_CATCH_MSG( "FAIL_CHECK", Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ ) #define SUCCEED( ... ) INTERNAL_CATCH_MSG( "SUCCEED", Catch::ResultWas::Ok, Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ ) #else #define TEST_CASE( name, description ) INTERNAL_CATCH_TESTCASE( name, description ) #define TEST_CASE_METHOD( className, name, description ) INTERNAL_CATCH_TEST_CASE_METHOD( className, name, description ) #define METHOD_AS_TEST_CASE( method, name, description ) INTERNAL_CATCH_METHOD_AS_TEST_CASE( method, name, description ) #define REGISTER_TEST_CASE( method, name, description ) INTERNAL_CATCH_REGISTER_TESTCASE( method, name, description ) #define SECTION( name, description ) INTERNAL_CATCH_SECTION( name, description ) #define FAIL( msg ) INTERNAL_CATCH_MSG( "FAIL", Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::Normal, msg ) #define FAIL_CHECK( msg ) INTERNAL_CATCH_MSG( "FAIL_CHECK", Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::ContinueOnFailure, msg ) #define SUCCEED( msg ) INTERNAL_CATCH_MSG( "SUCCEED", Catch::ResultWas::Ok, Catch::ResultDisposition::ContinueOnFailure, msg ) #endif #define ANON_TEST_CASE() INTERNAL_CATCH_TESTCASE( "", "" ) #define REGISTER_REPORTER( name, reporterType ) INTERNAL_CATCH_REGISTER_REPORTER( name, reporterType ) #define REGISTER_LEGACY_REPORTER( name, reporterType ) INTERNAL_CATCH_REGISTER_LEGACY_REPORTER( name, reporterType ) #define GENERATE( expr) INTERNAL_CATCH_GENERATE( expr ) #endif #define CATCH_TRANSLATE_EXCEPTION( signature ) INTERNAL_CATCH_TRANSLATE_EXCEPTION( signature ) // "BDD-style" convenience wrappers #ifdef CATCH_CONFIG_VARIADIC_MACROS #define SCENARIO( ... ) TEST_CASE( "Scenario: " __VA_ARGS__ ) #define SCENARIO_METHOD( className, ... ) INTERNAL_CATCH_TEST_CASE_METHOD( className, "Scenario: " __VA_ARGS__ ) #else #define SCENARIO( name, tags ) TEST_CASE( "Scenario: " name, tags ) #define SCENARIO_METHOD( className, name, tags ) INTERNAL_CATCH_TEST_CASE_METHOD( className, "Scenario: " name, tags ) #endif #define GIVEN( desc ) SECTION( std::string(" Given: ") + desc, "" ) #define WHEN( desc ) SECTION( std::string(" When: ") + desc, "" ) #define AND_WHEN( desc ) SECTION( std::string("And when: ") + desc, "" ) #define THEN( desc ) SECTION( std::string(" Then: ") + desc, "" ) #define AND_THEN( desc ) SECTION( std::string(" And: ") + desc, "" ) using Catch::Detail::Approx; #include "internal/catch_reenable_warnings.h" #endif // TWOBLUECUBES_CATCH_HPP_INCLUDED catch-1.12.1/include/catch_session.hpp000066400000000000000000000233411325474075300176540ustar00rootroot00000000000000/* * Created by Phil on 31/10/2010. * Copyright 2010 Two Blue Cubes Ltd. All rights reserved. * * Distributed under the Boost Software License, Version 1.0. (See accompanying * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) */ #ifndef TWOBLUECUBES_CATCH_RUNNER_HPP_INCLUDED #define TWOBLUECUBES_CATCH_RUNNER_HPP_INCLUDED #include "internal/catch_commandline.hpp" #include "internal/catch_list.hpp" #include "internal/catch_run_context.hpp" #include "internal/catch_test_spec.hpp" #include "internal/catch_version.h" #include "internal/catch_text.h" #include #include #include namespace Catch { Ptr createReporter( std::string const& reporterName, Ptr const& config ) { Ptr reporter = getRegistryHub().getReporterRegistry().create( reporterName, config.get() ); if( !reporter ) { std::ostringstream oss; oss << "No reporter registered with name: '" << reporterName << "'"; throw std::domain_error( oss.str() ); } return reporter; } #if !defined(CATCH_CONFIG_DEFAULT_REPORTER) #define CATCH_CONFIG_DEFAULT_REPORTER "console" #endif Ptr makeReporter( Ptr const& config ) { std::vector reporters = config->getReporterNames(); if( reporters.empty() ) reporters.push_back( CATCH_CONFIG_DEFAULT_REPORTER ); Ptr reporter; for( std::vector::const_iterator it = reporters.begin(), itEnd = reporters.end(); it != itEnd; ++it ) reporter = addReporter( reporter, createReporter( *it, config ) ); return reporter; } Ptr addListeners( Ptr const& config, Ptr reporters ) { IReporterRegistry::Listeners listeners = getRegistryHub().getReporterRegistry().getListeners(); for( IReporterRegistry::Listeners::const_iterator it = listeners.begin(), itEnd = listeners.end(); it != itEnd; ++it ) reporters = addReporter(reporters, (*it)->create( ReporterConfig( config ) ) ); return reporters; } Totals runTests( Ptr const& config ) { Ptr iconfig = config.get(); Ptr reporter = makeReporter( config ); reporter = addListeners( iconfig, reporter ); RunContext context( iconfig, reporter ); Totals totals; context.testGroupStarting( config->name(), 1, 1 ); TestSpec testSpec = config->testSpec(); if( !testSpec.hasFilters() ) testSpec = TestSpecParser( ITagAliasRegistry::get() ).parse( "~[.]" ).testSpec(); // All not hidden tests std::vector const& allTestCases = getAllTestCasesSorted( *iconfig ); for( std::vector::const_iterator it = allTestCases.begin(), itEnd = allTestCases.end(); it != itEnd; ++it ) { if( !context.aborting() && matchTest( *it, testSpec, *iconfig ) ) totals += context.runTest( *it ); else reporter->skipTest( *it ); } context.testGroupEnded( iconfig->name(), totals, 1, 1 ); return totals; } void applyFilenamesAsTags( IConfig const& config ) { std::vector const& tests = getAllTestCasesSorted( config ); for(std::size_t i = 0; i < tests.size(); ++i ) { TestCase& test = const_cast( tests[i] ); std::set tags = test.tags; std::string filename = test.lineInfo.file; std::string::size_type lastSlash = filename.find_last_of( "\\/" ); if( lastSlash != std::string::npos ) filename = filename.substr( lastSlash+1 ); std::string::size_type lastDot = filename.find_last_of( '.' ); if( lastDot != std::string::npos ) filename = filename.substr( 0, lastDot ); tags.insert( '#' + filename ); setTags( test, tags ); } } class Session : NonCopyable { static bool alreadyInstantiated; public: struct OnUnusedOptions { enum DoWhat { Ignore, Fail }; }; Session() : m_cli( makeCommandLineParser() ) { if( alreadyInstantiated ) { std::string msg = "Only one instance of Catch::Session can ever be used"; Catch::cerr() << msg << std::endl; throw std::logic_error( msg ); } alreadyInstantiated = true; } ~Session() { Catch::cleanUp(); } void showHelp( std::string const& processName ) { Catch::cout() << "\nCatch v" << libraryVersion() << "\n"; m_cli.usage( Catch::cout(), processName ); Catch::cout() << "For more detail usage please see the project docs\n" << std::endl; } void libIdentify() { Catch::cout() << std::left << std::setw(16) << "description: " << "A Catch test executable\n" << std::left << std::setw(16) << "category: " << "testframework\n" << std::left << std::setw(16) << "framework: " << "Catch Test\n" << std::left << std::setw(16) << "version: " << libraryVersion() << std::endl; } int applyCommandLine( int argc, char const* const* const argv, OnUnusedOptions::DoWhat unusedOptionBehaviour = OnUnusedOptions::Fail ) { try { m_cli.setThrowOnUnrecognisedTokens( unusedOptionBehaviour == OnUnusedOptions::Fail ); m_unusedTokens = m_cli.parseInto( Clara::argsToVector( argc, argv ), m_configData ); if( m_configData.showHelp ) showHelp( m_configData.processName ); if( m_configData.libIdentify ) libIdentify(); m_config.reset(); } catch( std::exception& ex ) { { Colour colourGuard( Colour::Red ); Catch::cerr() << "\nError(s) in input:\n" << Text( ex.what(), TextAttributes().setIndent(2) ) << "\n\n"; } m_cli.usage( Catch::cout(), m_configData.processName ); return (std::numeric_limits::max)(); } return 0; } void useConfigData( ConfigData const& _configData ) { m_configData = _configData; m_config.reset(); } int run( int argc, char const* const* const argv ) { int returnCode = applyCommandLine( argc, argv ); if( returnCode == 0 ) returnCode = run(); return returnCode; } #if defined(WIN32) && defined(UNICODE) int run( int argc, wchar_t const* const* const argv ) { char **utf8Argv = new char *[ argc ]; for ( int i = 0; i < argc; ++i ) { int bufSize = WideCharToMultiByte( CP_UTF8, 0, argv[i], -1, NULL, 0, NULL, NULL ); utf8Argv[ i ] = new char[ bufSize ]; WideCharToMultiByte( CP_UTF8, 0, argv[i], -1, utf8Argv[i], bufSize, NULL, NULL ); } int returnCode = applyCommandLine( argc, utf8Argv ); if( returnCode == 0 ) returnCode = run(); for ( int i = 0; i < argc; ++i ) delete [] utf8Argv[ i ]; delete [] utf8Argv; return returnCode; } #endif int run() { if( ( m_configData.waitForKeypress & WaitForKeypress::BeforeStart ) != 0 ) { Catch::cout() << "...waiting for enter/ return before starting" << std::endl; static_cast(std::getchar()); } int exitCode = runInternal(); if( ( m_configData.waitForKeypress & WaitForKeypress::BeforeExit ) != 0 ) { Catch::cout() << "...waiting for enter/ return before exiting, with code: " << exitCode << std::endl; static_cast(std::getchar()); } return exitCode; } Clara::CommandLine const& cli() const { return m_cli; } std::vector const& unusedTokens() const { return m_unusedTokens; } ConfigData& configData() { return m_configData; } Config& config() { if( !m_config ) m_config = new Config( m_configData ); return *m_config; } private: int runInternal() { if( m_configData.showHelp || m_configData.libIdentify ) return 0; try { config(); // Force config to be constructed seedRng( *m_config ); if( m_configData.filenamesAsTags ) applyFilenamesAsTags( *m_config ); // Handle list request if( Option listed = list( config() ) ) return static_cast( *listed ); return static_cast( runTests( m_config ).assertions.failed ); } catch( std::exception& ex ) { Catch::cerr() << ex.what() << std::endl; return (std::numeric_limits::max)(); } } Clara::CommandLine m_cli; std::vector m_unusedTokens; ConfigData m_configData; Ptr m_config; }; bool Session::alreadyInstantiated = false; } // end namespace Catch #endif // TWOBLUECUBES_CATCH_RUNNER_HPP_INCLUDED catch-1.12.1/include/catch_with_main.hpp000066400000000000000000000007161325474075300201510ustar00rootroot00000000000000 /* * Created by Phil on 01/11/2010. * Copyright 2010 Two Blue Cubes Ltd. All rights reserved. * * Distributed under the Boost Software License, Version 1.0. (See accompanying * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) */ #ifndef TWOBLUECUBES_CATCH_WITH_MAIN_HPP_INCLUDED #define TWOBLUECUBES_CATCH_WITH_MAIN_HPP_INCLUDED #define CATCH_CONFIG_MAIN #include "catch.hpp" #endif // TWOBLUECUBES_CATCH_WITH_MAIN_HPP_INCLUDED catch-1.12.1/include/external/000077500000000000000000000000001325474075300161355ustar00rootroot00000000000000catch-1.12.1/include/external/clara.h000066400000000000000000001202331325474075300173710ustar00rootroot00000000000000/* * Created by Phil on 25/05/2013. * Copyright 2013 Two Blue Cubes Ltd. All rights reserved. * * Distributed under the Boost Software License, Version 1.0. (See accompanying * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) */ // Version 0.0.2.4 // Only use header guard if we are not using an outer namespace #if !defined(TWOBLUECUBES_CLARA_H_INCLUDED) || defined(STITCH_CLARA_OPEN_NAMESPACE) #ifndef STITCH_CLARA_OPEN_NAMESPACE #define TWOBLUECUBES_CLARA_H_INCLUDED #define STITCH_CLARA_OPEN_NAMESPACE #define STITCH_CLARA_CLOSE_NAMESPACE #else #define STITCH_CLARA_CLOSE_NAMESPACE } #endif #define STITCH_TBC_TEXT_FORMAT_OPEN_NAMESPACE STITCH_CLARA_OPEN_NAMESPACE // ----------- #included from tbc_text_format.h ----------- /* * Created by Phil on 18/4/2013. * Copyright 2013 Two Blue Cubes Ltd. All rights reserved. * * Distributed under the Boost Software License, Version 1.0. (See accompanying * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) */ // Only use header guard if we are not using an outer namespace #if !defined(TBC_TEXT_FORMAT_H_INCLUDED) || defined(STITCH_TBC_TEXT_FORMAT_OUTER_NAMESPACE) #ifndef STITCH_TBC_TEXT_FORMAT_OUTER_NAMESPACE #define TBC_TEXT_FORMAT_H_INCLUDED #endif #include #include #include #include #include // Use optional outer namespace #ifdef STITCH_TBC_TEXT_FORMAT_OUTER_NAMESPACE namespace STITCH_TBC_TEXT_FORMAT_OUTER_NAMESPACE { #endif namespace Tbc { #ifdef TBC_TEXT_FORMAT_CONSOLE_WIDTH const unsigned int consoleWidth = TBC_TEXT_FORMAT_CONSOLE_WIDTH; #else const unsigned int consoleWidth = 80; #endif struct TextAttributes { TextAttributes() : initialIndent( std::string::npos ), indent( 0 ), width( consoleWidth-1 ), tabChar( '\t' ) {} TextAttributes& setInitialIndent( std::size_t _value ) { initialIndent = _value; return *this; } TextAttributes& setIndent( std::size_t _value ) { indent = _value; return *this; } TextAttributes& setWidth( std::size_t _value ) { width = _value; return *this; } TextAttributes& setTabChar( char _value ) { tabChar = _value; return *this; } std::size_t initialIndent; // indent of first line, or npos std::size_t indent; // indent of subsequent lines, or all if initialIndent is npos std::size_t width; // maximum width of text, including indent. Longer text will wrap char tabChar; // If this char is seen the indent is changed to current pos }; class Text { public: Text( std::string const& _str, TextAttributes const& _attr = TextAttributes() ) : attr( _attr ) { std::string wrappableChars = " [({.,/|\\-"; std::size_t indent = _attr.initialIndent != std::string::npos ? _attr.initialIndent : _attr.indent; std::string remainder = _str; while( !remainder.empty() ) { if( lines.size() >= 1000 ) { lines.push_back( "... message truncated due to excessive size" ); return; } std::size_t tabPos = std::string::npos; std::size_t width = (std::min)( remainder.size(), _attr.width - indent ); std::size_t pos = remainder.find_first_of( '\n' ); if( pos <= width ) { width = pos; } pos = remainder.find_last_of( _attr.tabChar, width ); if( pos != std::string::npos ) { tabPos = pos; if( remainder[width] == '\n' ) width--; remainder = remainder.substr( 0, tabPos ) + remainder.substr( tabPos+1 ); } if( width == remainder.size() ) { spliceLine( indent, remainder, width ); } else if( remainder[width] == '\n' ) { spliceLine( indent, remainder, width ); if( width <= 1 || remainder.size() != 1 ) remainder = remainder.substr( 1 ); indent = _attr.indent; } else { pos = remainder.find_last_of( wrappableChars, width ); if( pos != std::string::npos && pos > 0 ) { spliceLine( indent, remainder, pos ); if( remainder[0] == ' ' ) remainder = remainder.substr( 1 ); } else { spliceLine( indent, remainder, width-1 ); lines.back() += "-"; } if( lines.size() == 1 ) indent = _attr.indent; if( tabPos != std::string::npos ) indent += tabPos; } } } void spliceLine( std::size_t _indent, std::string& _remainder, std::size_t _pos ) { lines.push_back( std::string( _indent, ' ' ) + _remainder.substr( 0, _pos ) ); _remainder = _remainder.substr( _pos ); } typedef std::vector::const_iterator const_iterator; const_iterator begin() const { return lines.begin(); } const_iterator end() const { return lines.end(); } std::string const& last() const { return lines.back(); } std::size_t size() const { return lines.size(); } std::string const& operator[]( std::size_t _index ) const { return lines[_index]; } std::string toString() const { std::ostringstream oss; oss << *this; return oss.str(); } friend std::ostream& operator << ( std::ostream& _stream, Text const& _text ) { for( Text::const_iterator it = _text.begin(), itEnd = _text.end(); it != itEnd; ++it ) { if( it != _text.begin() ) _stream << "\n"; _stream << *it; } return _stream; } private: std::string str; TextAttributes attr; std::vector lines; }; } // end namespace Tbc #ifdef STITCH_TBC_TEXT_FORMAT_OUTER_NAMESPACE } // end outer namespace #endif #endif // TBC_TEXT_FORMAT_H_INCLUDED // ----------- end of #include from tbc_text_format.h ----------- // ........... back in clara.h #undef STITCH_TBC_TEXT_FORMAT_OPEN_NAMESPACE // ----------- #included from clara_compilers.h ----------- /* * Created by Phil on 10/02/2016. * Copyright 2016 Two Blue Cubes Ltd. All rights reserved. * * Distributed under the Boost Software License, Version 1.0. (See accompanying * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) */ #ifndef TWOBLUECUBES_CLARA_COMPILERS_H_INCLUDED #define TWOBLUECUBES_CLARA_COMPILERS_H_INCLUDED // Detect a number of compiler features - mostly C++11/14 conformance - by compiler // The following features are defined: // // CLARA_CONFIG_CPP11_NULLPTR : is nullptr supported? // CLARA_CONFIG_CPP11_NOEXCEPT : is noexcept supported? // CLARA_CONFIG_CPP11_GENERATED_METHODS : The delete and default keywords for compiler generated methods // CLARA_CONFIG_CPP11_OVERRIDE : is override supported? // CLARA_CONFIG_CPP11_UNIQUE_PTR : is unique_ptr supported (otherwise use auto_ptr) // CLARA_CONFIG_CPP11_OR_GREATER : Is C++11 supported? // CLARA_CONFIG_VARIADIC_MACROS : are variadic macros supported? // In general each macro has a _NO_ form // (e.g. CLARA_CONFIG_CPP11_NO_NULLPTR) which disables the feature. // Many features, at point of detection, define an _INTERNAL_ macro, so they // can be combined, en-mass, with the _NO_ forms later. // All the C++11 features can be disabled with CLARA_CONFIG_NO_CPP11 #ifdef __clang__ #if __has_feature(cxx_nullptr) #define CLARA_INTERNAL_CONFIG_CPP11_NULLPTR #endif #if __has_feature(cxx_noexcept) #define CLARA_INTERNAL_CONFIG_CPP11_NOEXCEPT #endif #endif // __clang__ //////////////////////////////////////////////////////////////////////////////// // GCC #ifdef __GNUC__ #if __GNUC__ == 4 && __GNUC_MINOR__ >= 6 && defined(__GXX_EXPERIMENTAL_CXX0X__) #define CLARA_INTERNAL_CONFIG_CPP11_NULLPTR #endif // - otherwise more recent versions define __cplusplus >= 201103L // and will get picked up below #endif // __GNUC__ //////////////////////////////////////////////////////////////////////////////// // Visual C++ #ifdef _MSC_VER #if (_MSC_VER >= 1600) #define CLARA_INTERNAL_CONFIG_CPP11_NULLPTR #define CLARA_INTERNAL_CONFIG_CPP11_UNIQUE_PTR #endif #if (_MSC_VER >= 1900 ) // (VC++ 13 (VS2015)) #define CLARA_INTERNAL_CONFIG_CPP11_NOEXCEPT #define CLARA_INTERNAL_CONFIG_CPP11_GENERATED_METHODS #endif #endif // _MSC_VER //////////////////////////////////////////////////////////////////////////////// // C++ language feature support // catch all support for C++11 #if defined(__cplusplus) && __cplusplus >= 201103L #define CLARA_CPP11_OR_GREATER #if !defined(CLARA_INTERNAL_CONFIG_CPP11_NULLPTR) #define CLARA_INTERNAL_CONFIG_CPP11_NULLPTR #endif #ifndef CLARA_INTERNAL_CONFIG_CPP11_NOEXCEPT #define CLARA_INTERNAL_CONFIG_CPP11_NOEXCEPT #endif #ifndef CLARA_INTERNAL_CONFIG_CPP11_GENERATED_METHODS #define CLARA_INTERNAL_CONFIG_CPP11_GENERATED_METHODS #endif #if !defined(CLARA_INTERNAL_CONFIG_CPP11_OVERRIDE) #define CLARA_INTERNAL_CONFIG_CPP11_OVERRIDE #endif #if !defined(CLARA_INTERNAL_CONFIG_CPP11_UNIQUE_PTR) #define CLARA_INTERNAL_CONFIG_CPP11_UNIQUE_PTR #endif #endif // __cplusplus >= 201103L // Now set the actual defines based on the above + anything the user has configured #if defined(CLARA_INTERNAL_CONFIG_CPP11_NULLPTR) && !defined(CLARA_CONFIG_CPP11_NO_NULLPTR) && !defined(CLARA_CONFIG_CPP11_NULLPTR) && !defined(CLARA_CONFIG_NO_CPP11) #define CLARA_CONFIG_CPP11_NULLPTR #endif #if defined(CLARA_INTERNAL_CONFIG_CPP11_NOEXCEPT) && !defined(CLARA_CONFIG_CPP11_NO_NOEXCEPT) && !defined(CLARA_CONFIG_CPP11_NOEXCEPT) && !defined(CLARA_CONFIG_NO_CPP11) #define CLARA_CONFIG_CPP11_NOEXCEPT #endif #if defined(CLARA_INTERNAL_CONFIG_CPP11_GENERATED_METHODS) && !defined(CLARA_CONFIG_CPP11_NO_GENERATED_METHODS) && !defined(CLARA_CONFIG_CPP11_GENERATED_METHODS) && !defined(CLARA_CONFIG_NO_CPP11) #define CLARA_CONFIG_CPP11_GENERATED_METHODS #endif #if defined(CLARA_INTERNAL_CONFIG_CPP11_OVERRIDE) && !defined(CLARA_CONFIG_NO_OVERRIDE) && !defined(CLARA_CONFIG_CPP11_OVERRIDE) && !defined(CLARA_CONFIG_NO_CPP11) #define CLARA_CONFIG_CPP11_OVERRIDE #endif #if defined(CLARA_INTERNAL_CONFIG_CPP11_UNIQUE_PTR) && !defined(CLARA_CONFIG_NO_UNIQUE_PTR) && !defined(CLARA_CONFIG_CPP11_UNIQUE_PTR) && !defined(CLARA_CONFIG_NO_CPP11) #define CLARA_CONFIG_CPP11_UNIQUE_PTR #endif // noexcept support: #if defined(CLARA_CONFIG_CPP11_NOEXCEPT) && !defined(CLARA_NOEXCEPT) #define CLARA_NOEXCEPT noexcept # define CLARA_NOEXCEPT_IS(x) noexcept(x) #else #define CLARA_NOEXCEPT throw() # define CLARA_NOEXCEPT_IS(x) #endif // nullptr support #ifdef CLARA_CONFIG_CPP11_NULLPTR #define CLARA_NULL nullptr #else #define CLARA_NULL NULL #endif // override support #ifdef CLARA_CONFIG_CPP11_OVERRIDE #define CLARA_OVERRIDE override #else #define CLARA_OVERRIDE #endif // unique_ptr support #ifdef CLARA_CONFIG_CPP11_UNIQUE_PTR # define CLARA_AUTO_PTR( T ) std::unique_ptr #else # define CLARA_AUTO_PTR( T ) std::auto_ptr #endif #endif // TWOBLUECUBES_CLARA_COMPILERS_H_INCLUDED // ----------- end of #include from clara_compilers.h ----------- // ........... back in clara.h #include #include #include #if defined(WIN32) || defined(__WIN32__) || defined(_WIN32) || defined(_MSC_VER) #define CLARA_PLATFORM_WINDOWS #endif // Use optional outer namespace #ifdef STITCH_CLARA_OPEN_NAMESPACE STITCH_CLARA_OPEN_NAMESPACE #endif namespace Clara { struct UnpositionalTag {}; extern UnpositionalTag _; #ifdef CLARA_CONFIG_MAIN UnpositionalTag _; #endif namespace Detail { #ifdef CLARA_CONSOLE_WIDTH const unsigned int consoleWidth = CLARA_CONFIG_CONSOLE_WIDTH; #else const unsigned int consoleWidth = 80; #endif using namespace Tbc; inline bool startsWith( std::string const& str, std::string const& prefix ) { return str.size() >= prefix.size() && str.substr( 0, prefix.size() ) == prefix; } template struct RemoveConstRef{ typedef T type; }; template struct RemoveConstRef{ typedef T type; }; template struct RemoveConstRef{ typedef T type; }; template struct RemoveConstRef{ typedef T type; }; template struct IsBool { static const bool value = false; }; template<> struct IsBool { static const bool value = true; }; template void convertInto( std::string const& _source, T& _dest ) { std::stringstream ss; ss << _source; ss >> _dest; if( ss.fail() ) throw std::runtime_error( "Unable to convert " + _source + " to destination type" ); } inline void convertInto( std::string const& _source, std::string& _dest ) { _dest = _source; } char toLowerCh(char c) { return static_cast( std::tolower( c ) ); } inline void convertInto( std::string const& _source, bool& _dest ) { std::string sourceLC = _source; std::transform( sourceLC.begin(), sourceLC.end(), sourceLC.begin(), toLowerCh ); if( sourceLC == "y" || sourceLC == "1" || sourceLC == "true" || sourceLC == "yes" || sourceLC == "on" ) _dest = true; else if( sourceLC == "n" || sourceLC == "0" || sourceLC == "false" || sourceLC == "no" || sourceLC == "off" ) _dest = false; else throw std::runtime_error( "Expected a boolean value but did not recognise:\n '" + _source + "'" ); } template struct IArgFunction { virtual ~IArgFunction() {} #ifdef CLARA_CONFIG_CPP11_GENERATED_METHODS IArgFunction() = default; IArgFunction( IArgFunction const& ) = default; #endif virtual void set( ConfigT& config, std::string const& value ) const = 0; virtual bool takesArg() const = 0; virtual IArgFunction* clone() const = 0; }; template class BoundArgFunction { public: BoundArgFunction() : functionObj( CLARA_NULL ) {} BoundArgFunction( IArgFunction* _functionObj ) : functionObj( _functionObj ) {} BoundArgFunction( BoundArgFunction const& other ) : functionObj( other.functionObj ? other.functionObj->clone() : CLARA_NULL ) {} BoundArgFunction& operator = ( BoundArgFunction const& other ) { IArgFunction* newFunctionObj = other.functionObj ? other.functionObj->clone() : CLARA_NULL; delete functionObj; functionObj = newFunctionObj; return *this; } ~BoundArgFunction() { delete functionObj; } void set( ConfigT& config, std::string const& value ) const { functionObj->set( config, value ); } bool takesArg() const { return functionObj->takesArg(); } bool isSet() const { return functionObj != CLARA_NULL; } private: IArgFunction* functionObj; }; template struct NullBinder : IArgFunction{ virtual void set( C&, std::string const& ) const {} virtual bool takesArg() const { return true; } virtual IArgFunction* clone() const { return new NullBinder( *this ); } }; template struct BoundDataMember : IArgFunction{ BoundDataMember( M C::* _member ) : member( _member ) {} virtual void set( C& p, std::string const& stringValue ) const { convertInto( stringValue, p.*member ); } virtual bool takesArg() const { return !IsBool::value; } virtual IArgFunction* clone() const { return new BoundDataMember( *this ); } M C::* member; }; template struct BoundUnaryMethod : IArgFunction{ BoundUnaryMethod( void (C::*_member)( M ) ) : member( _member ) {} virtual void set( C& p, std::string const& stringValue ) const { typename RemoveConstRef::type value; convertInto( stringValue, value ); (p.*member)( value ); } virtual bool takesArg() const { return !IsBool::value; } virtual IArgFunction* clone() const { return new BoundUnaryMethod( *this ); } void (C::*member)( M ); }; template struct BoundNullaryMethod : IArgFunction{ BoundNullaryMethod( void (C::*_member)() ) : member( _member ) {} virtual void set( C& p, std::string const& stringValue ) const { bool value; convertInto( stringValue, value ); if( value ) (p.*member)(); } virtual bool takesArg() const { return false; } virtual IArgFunction* clone() const { return new BoundNullaryMethod( *this ); } void (C::*member)(); }; template struct BoundUnaryFunction : IArgFunction{ BoundUnaryFunction( void (*_function)( C& ) ) : function( _function ) {} virtual void set( C& obj, std::string const& stringValue ) const { bool value; convertInto( stringValue, value ); if( value ) function( obj ); } virtual bool takesArg() const { return false; } virtual IArgFunction* clone() const { return new BoundUnaryFunction( *this ); } void (*function)( C& ); }; template struct BoundBinaryFunction : IArgFunction{ BoundBinaryFunction( void (*_function)( C&, T ) ) : function( _function ) {} virtual void set( C& obj, std::string const& stringValue ) const { typename RemoveConstRef::type value; convertInto( stringValue, value ); function( obj, value ); } virtual bool takesArg() const { return !IsBool::value; } virtual IArgFunction* clone() const { return new BoundBinaryFunction( *this ); } void (*function)( C&, T ); }; } // namespace Detail inline std::vector argsToVector( int argc, char const* const* const argv ) { std::vector args( static_cast( argc ) ); for( std::size_t i = 0; i < static_cast( argc ); ++i ) args[i] = argv[i]; return args; } class Parser { enum Mode { None, MaybeShortOpt, SlashOpt, ShortOpt, LongOpt, Positional }; Mode mode; std::size_t from; bool inQuotes; public: struct Token { enum Type { Positional, ShortOpt, LongOpt }; Token( Type _type, std::string const& _data ) : type( _type ), data( _data ) {} Type type; std::string data; }; Parser() : mode( None ), from( 0 ), inQuotes( false ){} void parseIntoTokens( std::vector const& args, std::vector& tokens ) { const std::string doubleDash = "--"; for( std::size_t i = 1; i < args.size() && args[i] != doubleDash; ++i ) parseIntoTokens( args[i], tokens); } void parseIntoTokens( std::string const& arg, std::vector& tokens ) { for( std::size_t i = 0; i < arg.size(); ++i ) { char c = arg[i]; if( c == '"' ) inQuotes = !inQuotes; mode = handleMode( i, c, arg, tokens ); } mode = handleMode( arg.size(), '\0', arg, tokens ); } Mode handleMode( std::size_t i, char c, std::string const& arg, std::vector& tokens ) { switch( mode ) { case None: return handleNone( i, c ); case MaybeShortOpt: return handleMaybeShortOpt( i, c ); case ShortOpt: case LongOpt: case SlashOpt: return handleOpt( i, c, arg, tokens ); case Positional: return handlePositional( i, c, arg, tokens ); default: throw std::logic_error( "Unknown mode" ); } } Mode handleNone( std::size_t i, char c ) { if( inQuotes ) { from = i; return Positional; } switch( c ) { case '-': return MaybeShortOpt; #ifdef CLARA_PLATFORM_WINDOWS case '/': from = i+1; return SlashOpt; #endif default: from = i; return Positional; } } Mode handleMaybeShortOpt( std::size_t i, char c ) { switch( c ) { case '-': from = i+1; return LongOpt; default: from = i; return ShortOpt; } } Mode handleOpt( std::size_t i, char c, std::string const& arg, std::vector& tokens ) { if( std::string( ":=\0", 3 ).find( c ) == std::string::npos ) return mode; std::string optName = arg.substr( from, i-from ); if( mode == ShortOpt ) for( std::size_t j = 0; j < optName.size(); ++j ) tokens.push_back( Token( Token::ShortOpt, optName.substr( j, 1 ) ) ); else if( mode == SlashOpt && optName.size() == 1 ) tokens.push_back( Token( Token::ShortOpt, optName ) ); else tokens.push_back( Token( Token::LongOpt, optName ) ); return None; } Mode handlePositional( std::size_t i, char c, std::string const& arg, std::vector& tokens ) { if( inQuotes || std::string( "\0", 1 ).find( c ) == std::string::npos ) return mode; std::string data = arg.substr( from, i-from ); tokens.push_back( Token( Token::Positional, data ) ); return None; } }; template struct CommonArgProperties { CommonArgProperties() {} CommonArgProperties( Detail::BoundArgFunction const& _boundField ) : boundField( _boundField ) {} Detail::BoundArgFunction boundField; std::string description; std::string detail; std::string placeholder; // Only value if boundField takes an arg bool takesArg() const { return !placeholder.empty(); } void validate() const { if( !boundField.isSet() ) throw std::logic_error( "option not bound" ); } }; struct OptionArgProperties { std::vector shortNames; std::string longName; bool hasShortName( std::string const& shortName ) const { return std::find( shortNames.begin(), shortNames.end(), shortName ) != shortNames.end(); } bool hasLongName( std::string const& _longName ) const { return _longName == longName; } }; struct PositionalArgProperties { PositionalArgProperties() : position( -1 ) {} int position; // -1 means non-positional (floating) bool isFixedPositional() const { return position != -1; } }; template class CommandLine { struct Arg : CommonArgProperties, OptionArgProperties, PositionalArgProperties { Arg() {} Arg( Detail::BoundArgFunction const& _boundField ) : CommonArgProperties( _boundField ) {} using CommonArgProperties::placeholder; // !TBD std::string dbgName() const { if( !longName.empty() ) return "--" + longName; if( !shortNames.empty() ) return "-" + shortNames[0]; return "positional args"; } std::string commands() const { std::ostringstream oss; bool first = true; std::vector::const_iterator it = shortNames.begin(), itEnd = shortNames.end(); for(; it != itEnd; ++it ) { if( first ) first = false; else oss << ", "; oss << "-" << *it; } if( !longName.empty() ) { if( !first ) oss << ", "; oss << "--" << longName; } if( !placeholder.empty() ) oss << " <" << placeholder << ">"; return oss.str(); } }; typedef CLARA_AUTO_PTR( Arg ) ArgAutoPtr; friend void addOptName( Arg& arg, std::string const& optName ) { if( optName.empty() ) return; if( Detail::startsWith( optName, "--" ) ) { if( !arg.longName.empty() ) throw std::logic_error( "Only one long opt may be specified. '" + arg.longName + "' already specified, now attempting to add '" + optName + "'" ); arg.longName = optName.substr( 2 ); } else if( Detail::startsWith( optName, "-" ) ) arg.shortNames.push_back( optName.substr( 1 ) ); else throw std::logic_error( "option must begin with - or --. Option was: '" + optName + "'" ); } friend void setPositionalArg( Arg& arg, int position ) { arg.position = position; } class ArgBuilder { public: ArgBuilder( Arg* arg ) : m_arg( arg ) {} // Bind a non-boolean data member (requires placeholder string) template void bind( M C::* field, std::string const& placeholder ) { m_arg->boundField = new Detail::BoundDataMember( field ); m_arg->placeholder = placeholder; } // Bind a boolean data member (no placeholder required) template void bind( bool C::* field ) { m_arg->boundField = new Detail::BoundDataMember( field ); } // Bind a method taking a single, non-boolean argument (requires a placeholder string) template void bind( void (C::* unaryMethod)( M ), std::string const& placeholder ) { m_arg->boundField = new Detail::BoundUnaryMethod( unaryMethod ); m_arg->placeholder = placeholder; } // Bind a method taking a single, boolean argument (no placeholder string required) template void bind( void (C::* unaryMethod)( bool ) ) { m_arg->boundField = new Detail::BoundUnaryMethod( unaryMethod ); } // Bind a method that takes no arguments (will be called if opt is present) template void bind( void (C::* nullaryMethod)() ) { m_arg->boundField = new Detail::BoundNullaryMethod( nullaryMethod ); } // Bind a free function taking a single argument - the object to operate on (no placeholder string required) template void bind( void (* unaryFunction)( C& ) ) { m_arg->boundField = new Detail::BoundUnaryFunction( unaryFunction ); } // Bind a free function taking a single argument - the object to operate on (requires a placeholder string) template void bind( void (* binaryFunction)( C&, T ), std::string const& placeholder ) { m_arg->boundField = new Detail::BoundBinaryFunction( binaryFunction ); m_arg->placeholder = placeholder; } ArgBuilder& describe( std::string const& description ) { m_arg->description = description; return *this; } ArgBuilder& detail( std::string const& detail ) { m_arg->detail = detail; return *this; } protected: Arg* m_arg; }; class OptBuilder : public ArgBuilder { public: OptBuilder( Arg* arg ) : ArgBuilder( arg ) {} OptBuilder( OptBuilder& other ) : ArgBuilder( other ) {} OptBuilder& operator[]( std::string const& optName ) { addOptName( *ArgBuilder::m_arg, optName ); return *this; } }; public: CommandLine() : m_boundProcessName( new Detail::NullBinder() ), m_highestSpecifiedArgPosition( 0 ), m_throwOnUnrecognisedTokens( false ) {} CommandLine( CommandLine const& other ) : m_boundProcessName( other.m_boundProcessName ), m_options ( other.m_options ), m_positionalArgs( other.m_positionalArgs ), m_highestSpecifiedArgPosition( other.m_highestSpecifiedArgPosition ), m_throwOnUnrecognisedTokens( other.m_throwOnUnrecognisedTokens ) { if( other.m_floatingArg.get() ) m_floatingArg.reset( new Arg( *other.m_floatingArg ) ); } CommandLine& setThrowOnUnrecognisedTokens( bool shouldThrow = true ) { m_throwOnUnrecognisedTokens = shouldThrow; return *this; } OptBuilder operator[]( std::string const& optName ) { m_options.push_back( Arg() ); addOptName( m_options.back(), optName ); OptBuilder builder( &m_options.back() ); return builder; } ArgBuilder operator[]( int position ) { m_positionalArgs.insert( std::make_pair( position, Arg() ) ); if( position > m_highestSpecifiedArgPosition ) m_highestSpecifiedArgPosition = position; setPositionalArg( m_positionalArgs[position], position ); ArgBuilder builder( &m_positionalArgs[position] ); return builder; } // Invoke this with the _ instance ArgBuilder operator[]( UnpositionalTag ) { if( m_floatingArg.get() ) throw std::logic_error( "Only one unpositional argument can be added" ); m_floatingArg.reset( new Arg() ); ArgBuilder builder( m_floatingArg.get() ); return builder; } template void bindProcessName( M C::* field ) { m_boundProcessName = new Detail::BoundDataMember( field ); } template void bindProcessName( void (C::*_unaryMethod)( M ) ) { m_boundProcessName = new Detail::BoundUnaryMethod( _unaryMethod ); } void optUsage( std::ostream& os, std::size_t indent = 0, std::size_t width = Detail::consoleWidth ) const { typename std::vector::const_iterator itBegin = m_options.begin(), itEnd = m_options.end(), it; std::size_t maxWidth = 0; for( it = itBegin; it != itEnd; ++it ) maxWidth = (std::max)( maxWidth, it->commands().size() ); for( it = itBegin; it != itEnd; ++it ) { Detail::Text usage( it->commands(), Detail::TextAttributes() .setWidth( maxWidth+indent ) .setIndent( indent ) ); Detail::Text desc( it->description, Detail::TextAttributes() .setWidth( width - maxWidth - 3 ) ); for( std::size_t i = 0; i < (std::max)( usage.size(), desc.size() ); ++i ) { std::string usageCol = i < usage.size() ? usage[i] : ""; os << usageCol; if( i < desc.size() && !desc[i].empty() ) os << std::string( indent + 2 + maxWidth - usageCol.size(), ' ' ) << desc[i]; os << "\n"; } } } std::string optUsage() const { std::ostringstream oss; optUsage( oss ); return oss.str(); } void argSynopsis( std::ostream& os ) const { for( int i = 1; i <= m_highestSpecifiedArgPosition; ++i ) { if( i > 1 ) os << " "; typename std::map::const_iterator it = m_positionalArgs.find( i ); if( it != m_positionalArgs.end() ) os << "<" << it->second.placeholder << ">"; else if( m_floatingArg.get() ) os << "<" << m_floatingArg->placeholder << ">"; else throw std::logic_error( "non consecutive positional arguments with no floating args" ); } // !TBD No indication of mandatory args if( m_floatingArg.get() ) { if( m_highestSpecifiedArgPosition > 1 ) os << " "; os << "[<" << m_floatingArg->placeholder << "> ...]"; } } std::string argSynopsis() const { std::ostringstream oss; argSynopsis( oss ); return oss.str(); } void usage( std::ostream& os, std::string const& procName ) const { validate(); os << "usage:\n " << procName << " "; argSynopsis( os ); if( !m_options.empty() ) { os << " [options]\n\nwhere options are: \n"; optUsage( os, 2 ); } os << "\n"; } std::string usage( std::string const& procName ) const { std::ostringstream oss; usage( oss, procName ); return oss.str(); } ConfigT parse( std::vector const& args ) const { ConfigT config; parseInto( args, config ); return config; } std::vector parseInto( std::vector const& args, ConfigT& config ) const { std::string processName = args.empty() ? std::string() : args[0]; std::size_t lastSlash = processName.find_last_of( "/\\" ); if( lastSlash != std::string::npos ) processName = processName.substr( lastSlash+1 ); m_boundProcessName.set( config, processName ); std::vector tokens; Parser parser; parser.parseIntoTokens( args, tokens ); return populate( tokens, config ); } std::vector populate( std::vector const& tokens, ConfigT& config ) const { validate(); std::vector unusedTokens = populateOptions( tokens, config ); unusedTokens = populateFixedArgs( unusedTokens, config ); unusedTokens = populateFloatingArgs( unusedTokens, config ); return unusedTokens; } std::vector populateOptions( std::vector const& tokens, ConfigT& config ) const { std::vector unusedTokens; std::vector errors; for( std::size_t i = 0; i < tokens.size(); ++i ) { Parser::Token const& token = tokens[i]; typename std::vector::const_iterator it = m_options.begin(), itEnd = m_options.end(); for(; it != itEnd; ++it ) { Arg const& arg = *it; try { if( ( token.type == Parser::Token::ShortOpt && arg.hasShortName( token.data ) ) || ( token.type == Parser::Token::LongOpt && arg.hasLongName( token.data ) ) ) { if( arg.takesArg() ) { if( i == tokens.size()-1 || tokens[i+1].type != Parser::Token::Positional ) errors.push_back( "Expected argument to option: " + token.data ); else arg.boundField.set( config, tokens[++i].data ); } else { arg.boundField.set( config, "true" ); } break; } } catch( std::exception& ex ) { errors.push_back( std::string( ex.what() ) + "\n- while parsing: (" + arg.commands() + ")" ); } } if( it == itEnd ) { if( token.type == Parser::Token::Positional || !m_throwOnUnrecognisedTokens ) unusedTokens.push_back( token ); else if( errors.empty() && m_throwOnUnrecognisedTokens ) errors.push_back( "unrecognised option: " + token.data ); } } if( !errors.empty() ) { std::ostringstream oss; for( std::vector::const_iterator it = errors.begin(), itEnd = errors.end(); it != itEnd; ++it ) { if( it != errors.begin() ) oss << "\n"; oss << *it; } throw std::runtime_error( oss.str() ); } return unusedTokens; } std::vector populateFixedArgs( std::vector const& tokens, ConfigT& config ) const { std::vector unusedTokens; int position = 1; for( std::size_t i = 0; i < tokens.size(); ++i ) { Parser::Token const& token = tokens[i]; typename std::map::const_iterator it = m_positionalArgs.find( position ); if( it != m_positionalArgs.end() ) it->second.boundField.set( config, token.data ); else unusedTokens.push_back( token ); if( token.type == Parser::Token::Positional ) position++; } return unusedTokens; } std::vector populateFloatingArgs( std::vector const& tokens, ConfigT& config ) const { if( !m_floatingArg.get() ) return tokens; std::vector unusedTokens; for( std::size_t i = 0; i < tokens.size(); ++i ) { Parser::Token const& token = tokens[i]; if( token.type == Parser::Token::Positional ) m_floatingArg->boundField.set( config, token.data ); else unusedTokens.push_back( token ); } return unusedTokens; } void validate() const { if( m_options.empty() && m_positionalArgs.empty() && !m_floatingArg.get() ) throw std::logic_error( "No options or arguments specified" ); for( typename std::vector::const_iterator it = m_options.begin(), itEnd = m_options.end(); it != itEnd; ++it ) it->validate(); } private: Detail::BoundArgFunction m_boundProcessName; std::vector m_options; std::map m_positionalArgs; ArgAutoPtr m_floatingArg; int m_highestSpecifiedArgPosition; bool m_throwOnUnrecognisedTokens; }; } // end namespace Clara STITCH_CLARA_CLOSE_NAMESPACE #undef STITCH_CLARA_OPEN_NAMESPACE #undef STITCH_CLARA_CLOSE_NAMESPACE #endif // TWOBLUECUBES_CLARA_H_INCLUDED catch-1.12.1/include/external/tbc_text_format.h000066400000000000000000000141001325474075300214660ustar00rootroot00000000000000/* * Created by Phil on 18/4/2013. * Copyright 2013 Two Blue Cubes Ltd. All rights reserved. * * Distributed under the Boost Software License, Version 1.0. (See accompanying * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) */ // Only use header guard if we are not using an outer namespace #ifndef CLICHE_TBC_TEXT_FORMAT_OUTER_NAMESPACE # ifdef TWOBLUECUBES_TEXT_FORMAT_H_INCLUDED # ifndef TWOBLUECUBES_TEXT_FORMAT_H_ALREADY_INCLUDED # define TWOBLUECUBES_TEXT_FORMAT_H_ALREADY_INCLUDED # endif # else # define TWOBLUECUBES_TEXT_FORMAT_H_INCLUDED # endif #endif #ifndef TWOBLUECUBES_TEXT_FORMAT_H_ALREADY_INCLUDED #include #include #include // Use optional outer namespace #ifdef CLICHE_TBC_TEXT_FORMAT_OUTER_NAMESPACE namespace CLICHE_TBC_TEXT_FORMAT_OUTER_NAMESPACE { #endif namespace Tbc { #ifdef TBC_TEXT_FORMAT_CONSOLE_WIDTH const unsigned int consoleWidth = TBC_TEXT_FORMAT_CONSOLE_WIDTH; #else const unsigned int consoleWidth = 80; #endif struct TextAttributes { TextAttributes() : initialIndent( std::string::npos ), indent( 0 ), width( consoleWidth-1 ) {} TextAttributes& setInitialIndent( std::size_t _value ) { initialIndent = _value; return *this; } TextAttributes& setIndent( std::size_t _value ) { indent = _value; return *this; } TextAttributes& setWidth( std::size_t _value ) { width = _value; return *this; } std::size_t initialIndent; // indent of first line, or npos std::size_t indent; // indent of subsequent lines, or all if initialIndent is npos std::size_t width; // maximum width of text, including indent. Longer text will wrap }; class Text { public: Text( std::string const& _str, TextAttributes const& _attr = TextAttributes() ) : attr( _attr ) { const std::string wrappableBeforeChars = "[({<\t"; const std::string wrappableAfterChars = "])}>-,./|\\"; const std::string wrappableInsteadOfChars = " \n\r"; std::string indent = _attr.initialIndent != std::string::npos ? std::string( _attr.initialIndent, ' ' ) : std::string( _attr.indent, ' ' ); typedef std::string::const_iterator iterator; iterator it = _str.begin(); const iterator strEnd = _str.end(); while( it != strEnd ) { if( lines.size() >= 1000 ) { lines.push_back( "... message truncated due to excessive size" ); return; } std::string suffix; std::size_t width = (std::min)( static_cast( strEnd-it ), _attr.width-static_cast( indent.size() ) ); iterator itEnd = it+width; iterator itNext = _str.end(); iterator itNewLine = std::find( it, itEnd, '\n' ); if( itNewLine != itEnd ) itEnd = itNewLine; if( itEnd != strEnd ) { bool foundWrapPoint = false; iterator findIt = itEnd; do { if( wrappableAfterChars.find( *findIt ) != std::string::npos && findIt != itEnd ) { itEnd = findIt+1; itNext = findIt+1; foundWrapPoint = true; } else if( findIt > it && wrappableBeforeChars.find( *findIt ) != std::string::npos ) { itEnd = findIt; itNext = findIt; foundWrapPoint = true; } else if( wrappableInsteadOfChars.find( *findIt ) != std::string::npos ) { itNext = findIt+1; itEnd = findIt; foundWrapPoint = true; } if( findIt == it ) break; else --findIt; } while( !foundWrapPoint ); if( !foundWrapPoint ) { // No good wrap char, so we'll break mid word and add a hyphen --itEnd; itNext = itEnd; suffix = "-"; } else { while( itEnd > it && wrappableInsteadOfChars.find( *(itEnd-1) ) != std::string::npos ) --itEnd; } } lines.push_back( indent + std::string( it, itEnd ) + suffix ); if( indent.size() != _attr.indent ) indent = std::string( _attr.indent, ' ' ); it = itNext; } } typedef std::vector::const_iterator const_iterator; const_iterator begin() const { return lines.begin(); } const_iterator end() const { return lines.end(); } std::string const& last() const { return lines.back(); } std::size_t size() const { return lines.size(); } std::string const& operator[]( std::size_t _index ) const { return lines[_index]; } std::string toString() const { std::ostringstream oss; oss << *this; return oss.str(); } inline friend std::ostream& operator << ( std::ostream& _stream, Text const& _text ) { for( Text::const_iterator it = _text.begin(), itEnd = _text.end(); it != itEnd; ++it ) { if( it != _text.begin() ) _stream << "\n"; _stream << *it; } return _stream; } private: std::string str; TextAttributes attr; std::vector lines; }; } // end namespace Tbc #ifdef CLICHE_TBC_TEXT_FORMAT_OUTER_NAMESPACE } // end outer namespace #endif #endif // TWOBLUECUBES_TEXT_FORMAT_H_ALREADY_INCLUDED catch-1.12.1/include/internal/000077500000000000000000000000001325474075300161275ustar00rootroot00000000000000catch-1.12.1/include/internal/catch_approx.hpp000066400000000000000000000153231325474075300213170ustar00rootroot00000000000000/* * Created by Phil on 28/04/2011. * Copyright 2010 Two Blue Cubes Ltd. All rights reserved. * * Distributed under the Boost Software License, Version 1.0. (See accompanying * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) */ #ifndef TWOBLUECUBES_CATCH_APPROX_HPP_INCLUDED #define TWOBLUECUBES_CATCH_APPROX_HPP_INCLUDED #include "catch_tostring.h" #include #include #if defined(CATCH_CONFIG_CPP11_TYPE_TRAITS) #include #endif namespace Catch { namespace Detail { class Approx { public: explicit Approx ( double value ) : m_epsilon( std::numeric_limits::epsilon()*100 ), m_margin( 0.0 ), m_scale( 1.0 ), m_value( value ) {} static Approx custom() { return Approx( 0 ); } #if defined(CATCH_CONFIG_CPP11_TYPE_TRAITS) template ::value>::type> Approx operator()( T value ) { Approx approx( static_cast(value) ); approx.epsilon( m_epsilon ); approx.margin( m_margin ); approx.scale( m_scale ); return approx; } template ::value>::type> explicit Approx( T value ): Approx(static_cast(value)) {} template ::value>::type> friend bool operator == ( const T& lhs, Approx const& rhs ) { // Thanks to Richard Harris for his help refining this formula auto lhs_v = double(lhs); bool relativeOK = std::fabs(lhs_v - rhs.m_value) < rhs.m_epsilon * (rhs.m_scale + (std::max)(std::fabs(lhs_v), std::fabs(rhs.m_value))); if (relativeOK) { return true; } return std::fabs(lhs_v - rhs.m_value) <= rhs.m_margin; } template ::value>::type> friend bool operator == ( Approx const& lhs, const T& rhs ) { return operator==( rhs, lhs ); } template ::value>::type> friend bool operator != ( T lhs, Approx const& rhs ) { return !operator==( lhs, rhs ); } template ::value>::type> friend bool operator != ( Approx const& lhs, T rhs ) { return !operator==( rhs, lhs ); } template ::value>::type> friend bool operator <= ( T lhs, Approx const& rhs ) { return double(lhs) < rhs.m_value || lhs == rhs; } template ::value>::type> friend bool operator <= ( Approx const& lhs, T rhs ) { return lhs.m_value < double(rhs) || lhs == rhs; } template ::value>::type> friend bool operator >= ( T lhs, Approx const& rhs ) { return double(lhs) > rhs.m_value || lhs == rhs; } template ::value>::type> friend bool operator >= ( Approx const& lhs, T rhs ) { return lhs.m_value > double(rhs) || lhs == rhs; } template ::value>::type> Approx& epsilon( T newEpsilon ) { m_epsilon = double(newEpsilon); return *this; } template ::value>::type> Approx& margin( T newMargin ) { m_margin = double(newMargin); return *this; } template ::value>::type> Approx& scale( T newScale ) { m_scale = double(newScale); return *this; } #else Approx operator()( double value ) { Approx approx( value ); approx.epsilon( m_epsilon ); approx.margin( m_margin ); approx.scale( m_scale ); return approx; } friend bool operator == ( double lhs, Approx const& rhs ) { // Thanks to Richard Harris for his help refining this formula bool relativeOK = std::fabs( lhs - rhs.m_value ) < rhs.m_epsilon * (rhs.m_scale + (std::max)( std::fabs(lhs), std::fabs(rhs.m_value) ) ); if (relativeOK) { return true; } return std::fabs(lhs - rhs.m_value) <= rhs.m_margin; } friend bool operator == ( Approx const& lhs, double rhs ) { return operator==( rhs, lhs ); } friend bool operator != ( double lhs, Approx const& rhs ) { return !operator==( lhs, rhs ); } friend bool operator != ( Approx const& lhs, double rhs ) { return !operator==( rhs, lhs ); } friend bool operator <= ( double lhs, Approx const& rhs ) { return lhs < rhs.m_value || lhs == rhs; } friend bool operator <= ( Approx const& lhs, double rhs ) { return lhs.m_value < rhs || lhs == rhs; } friend bool operator >= ( double lhs, Approx const& rhs ) { return lhs > rhs.m_value || lhs == rhs; } friend bool operator >= ( Approx const& lhs, double rhs ) { return lhs.m_value > rhs || lhs == rhs; } Approx& epsilon( double newEpsilon ) { m_epsilon = newEpsilon; return *this; } Approx& margin( double newMargin ) { m_margin = newMargin; return *this; } Approx& scale( double newScale ) { m_scale = newScale; return *this; } #endif std::string toString() const { std::ostringstream oss; oss << "Approx( " << Catch::toString( m_value ) << " )"; return oss.str(); } private: double m_epsilon; double m_margin; double m_scale; double m_value; }; } template<> inline std::string toString( Detail::Approx const& value ) { return value.toString(); } } // end namespace Catch #endif // TWOBLUECUBES_CATCH_APPROX_HPP_INCLUDED catch-1.12.1/include/internal/catch_assertionresult.h000066400000000000000000000121741325474075300227150ustar00rootroot00000000000000/* * Created by Phil on 28/10/2010. * Copyright 2010 Two Blue Cubes Ltd. All rights reserved. * * Distributed under the Boost Software License, Version 1.0. (See accompanying * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) */ #ifndef TWOBLUECUBES_CATCH_ASSERTIONRESULT_H_INCLUDED #define TWOBLUECUBES_CATCH_ASSERTIONRESULT_H_INCLUDED #include #include "catch_result_type.h" namespace Catch { struct STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison; struct DecomposedExpression { virtual ~DecomposedExpression() {} virtual bool isBinaryExpression() const { return false; } virtual void reconstructExpression( std::string& dest ) const = 0; // Only simple binary comparisons can be decomposed. // If more complex check is required then wrap sub-expressions in parentheses. template STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator + ( T const& ); template STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator - ( T const& ); template STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator * ( T const& ); template STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator / ( T const& ); template STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator % ( T const& ); template STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator && ( T const& ); template STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator || ( T const& ); private: DecomposedExpression& operator = (DecomposedExpression const&); }; struct AssertionInfo { AssertionInfo(); AssertionInfo( char const * _macroName, SourceLineInfo const& _lineInfo, char const * _capturedExpression, ResultDisposition::Flags _resultDisposition, char const * _secondArg = ""); char const * macroName; SourceLineInfo lineInfo; char const * capturedExpression; ResultDisposition::Flags resultDisposition; char const * secondArg; }; struct AssertionResultData { AssertionResultData() : decomposedExpression( CATCH_NULL ) , resultType( ResultWas::Unknown ) , negated( false ) , parenthesized( false ) {} void negate( bool parenthesize ) { negated = !negated; parenthesized = parenthesize; if( resultType == ResultWas::Ok ) resultType = ResultWas::ExpressionFailed; else if( resultType == ResultWas::ExpressionFailed ) resultType = ResultWas::Ok; } std::string const& reconstructExpression() const { if( decomposedExpression != CATCH_NULL ) { decomposedExpression->reconstructExpression( reconstructedExpression ); if( parenthesized ) { reconstructedExpression.insert( 0, 1, '(' ); reconstructedExpression.append( 1, ')' ); } if( negated ) { reconstructedExpression.insert( 0, 1, '!' ); } decomposedExpression = CATCH_NULL; } return reconstructedExpression; } mutable DecomposedExpression const* decomposedExpression; mutable std::string reconstructedExpression; std::string message; ResultWas::OfType resultType; bool negated; bool parenthesized; }; class AssertionResult { public: AssertionResult(); AssertionResult( AssertionInfo const& info, AssertionResultData const& data ); ~AssertionResult(); # ifdef CATCH_CONFIG_CPP11_GENERATED_METHODS AssertionResult( AssertionResult const& ) = default; AssertionResult( AssertionResult && ) = default; AssertionResult& operator = ( AssertionResult const& ) = default; AssertionResult& operator = ( AssertionResult && ) = default; # endif bool isOk() const; bool succeeded() const; ResultWas::OfType getResultType() const; bool hasExpression() const; bool hasMessage() const; std::string getExpression() const; std::string getExpressionInMacro() const; bool hasExpandedExpression() const; std::string getExpandedExpression() const; std::string getMessage() const; SourceLineInfo getSourceInfo() const; std::string getTestMacroName() const; void discardDecomposedExpression() const; void expandDecomposedExpression() const; protected: AssertionInfo m_info; AssertionResultData m_resultData; }; } // end namespace Catch #endif // TWOBLUECUBES_CATCH_ASSERTIONRESULT_H_INCLUDED catch-1.12.1/include/internal/catch_assertionresult.hpp000066400000000000000000000075311325474075300232560ustar00rootroot00000000000000/* * Created by Phil on 8/8/12 * Copyright 2012 Two Blue Cubes Ltd. All rights reserved. * * Distributed under the Boost Software License, Version 1.0. (See accompanying * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) */ #ifndef TWOBLUECUBES_CATCH_ASSERTIONRESULT_HPP_INCLUDED #define TWOBLUECUBES_CATCH_ASSERTIONRESULT_HPP_INCLUDED #include "catch_assertionresult.h" namespace Catch { AssertionInfo::AssertionInfo():macroName(""), capturedExpression(""), resultDisposition(ResultDisposition::Normal), secondArg(""){} AssertionInfo::AssertionInfo( char const * _macroName, SourceLineInfo const& _lineInfo, char const * _capturedExpression, ResultDisposition::Flags _resultDisposition, char const * _secondArg) : macroName( _macroName ), lineInfo( _lineInfo ), capturedExpression( _capturedExpression ), resultDisposition( _resultDisposition ), secondArg( _secondArg ) {} AssertionResult::AssertionResult() {} AssertionResult::AssertionResult( AssertionInfo const& info, AssertionResultData const& data ) : m_info( info ), m_resultData( data ) {} AssertionResult::~AssertionResult() {} // Result was a success bool AssertionResult::succeeded() const { return Catch::isOk( m_resultData.resultType ); } // Result was a success, or failure is suppressed bool AssertionResult::isOk() const { return Catch::isOk( m_resultData.resultType ) || shouldSuppressFailure( m_info.resultDisposition ); } ResultWas::OfType AssertionResult::getResultType() const { return m_resultData.resultType; } bool AssertionResult::hasExpression() const { return m_info.capturedExpression[0] != 0; } bool AssertionResult::hasMessage() const { return !m_resultData.message.empty(); } std::string capturedExpressionWithSecondArgument( char const * capturedExpression, char const * secondArg ) { return (secondArg[0] == 0 || secondArg[0] == '"' && secondArg[1] == '"') ? capturedExpression : std::string(capturedExpression) + ", " + secondArg; } std::string AssertionResult::getExpression() const { if( isFalseTest( m_info.resultDisposition ) ) return "!(" + capturedExpressionWithSecondArgument(m_info.capturedExpression, m_info.secondArg) + ")"; else return capturedExpressionWithSecondArgument(m_info.capturedExpression, m_info.secondArg); } std::string AssertionResult::getExpressionInMacro() const { if( m_info.macroName[0] == 0 ) return capturedExpressionWithSecondArgument(m_info.capturedExpression, m_info.secondArg); else return std::string(m_info.macroName) + "( " + capturedExpressionWithSecondArgument(m_info.capturedExpression, m_info.secondArg) + " )"; } bool AssertionResult::hasExpandedExpression() const { return hasExpression() && getExpandedExpression() != getExpression(); } std::string AssertionResult::getExpandedExpression() const { return m_resultData.reconstructExpression(); } std::string AssertionResult::getMessage() const { return m_resultData.message; } SourceLineInfo AssertionResult::getSourceInfo() const { return m_info.lineInfo; } std::string AssertionResult::getTestMacroName() const { return m_info.macroName; } void AssertionResult::discardDecomposedExpression() const { m_resultData.decomposedExpression = CATCH_NULL; } void AssertionResult::expandDecomposedExpression() const { m_resultData.reconstructExpression(); } } // end namespace Catch #endif // TWOBLUECUBES_CATCH_ASSERTIONRESULT_HPP_INCLUDED catch-1.12.1/include/internal/catch_capture.hpp000066400000000000000000000221241325474075300214460ustar00rootroot00000000000000/* * Created by Phil on 18/10/2010. * Copyright 2010 Two Blue Cubes Ltd. All rights reserved. * * Distributed under the Boost Software License, Version 1.0. (See accompanying * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) */ #ifndef TWOBLUECUBES_CATCH_CAPTURE_HPP_INCLUDED #define TWOBLUECUBES_CATCH_CAPTURE_HPP_INCLUDED #include "catch_result_builder.h" #include "catch_message.h" #include "catch_interfaces_capture.h" #include "catch_debugger.h" #include "catch_common.h" #include "catch_tostring.h" #include "catch_interfaces_runner.h" #include "catch_compiler_capabilities.h" #if !defined(CATCH_CONFIG_DISABLE_STRINGIFICATION) # define CATCH_INTERNAL_STRINGIFY(expr) #expr #else # define CATCH_INTERNAL_STRINGIFY(expr) "Disabled by CATCH_CONFIG_DISABLE_STRINGIFICATION" #endif #if defined(CATCH_CONFIG_FAST_COMPILE) /////////////////////////////////////////////////////////////////////////////// // We can speedup compilation significantly by breaking into debugger lower in // the callstack, because then we don't have to expand CATCH_BREAK_INTO_DEBUGGER // macro in each assertion #define INTERNAL_CATCH_REACT( resultBuilder ) \ resultBuilder.react(); /////////////////////////////////////////////////////////////////////////////// // Another way to speed-up compilation is to omit local try-catch for REQUIRE* // macros. // This can potentially cause false negative, if the test code catches // the exception before it propagates back up to the runner. #define INTERNAL_CATCH_TEST_NO_TRY( macroName, resultDisposition, expr ) \ do { \ Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(expr), resultDisposition ); \ __catchResult.setExceptionGuard(); \ CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS \ ( __catchResult <= expr ).endExpression(); \ CATCH_INTERNAL_UNSUPPRESS_PARENTHESES_WARNINGS \ __catchResult.unsetExceptionGuard(); \ INTERNAL_CATCH_REACT( __catchResult ) \ } while( Catch::isTrue( false && static_cast( !!(expr) ) ) ) // expr here is never evaluated at runtime but it forces the compiler to give it a look // The double negation silences MSVC's C4800 warning, the static_cast forces short-circuit evaluation if the type has overloaded &&. #define INTERNAL_CHECK_THAT_NO_TRY( macroName, matcher, resultDisposition, arg ) \ do { \ Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(arg) ", " CATCH_INTERNAL_STRINGIFY(matcher), resultDisposition ); \ __catchResult.setExceptionGuard(); \ __catchResult.captureMatch( arg, matcher, CATCH_INTERNAL_STRINGIFY(matcher) ); \ __catchResult.unsetExceptionGuard(); \ INTERNAL_CATCH_REACT( __catchResult ) \ } while( Catch::alwaysFalse() ) #else /////////////////////////////////////////////////////////////////////////////// // In the event of a failure works out if the debugger needs to be invoked // and/or an exception thrown and takes appropriate action. // This needs to be done as a macro so the debugger will stop in the user // source code rather than in Catch library code #define INTERNAL_CATCH_REACT( resultBuilder ) \ if( resultBuilder.shouldDebugBreak() ) CATCH_BREAK_INTO_DEBUGGER(); \ resultBuilder.react(); #endif /////////////////////////////////////////////////////////////////////////////// #define INTERNAL_CATCH_TEST( macroName, resultDisposition, expr ) \ do { \ Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(expr), resultDisposition ); \ try { \ CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS \ ( __catchResult <= expr ).endExpression(); \ CATCH_INTERNAL_UNSUPPRESS_PARENTHESES_WARNINGS \ } \ catch( ... ) { \ __catchResult.useActiveException( resultDisposition ); \ } \ INTERNAL_CATCH_REACT( __catchResult ) \ } while( Catch::isTrue( false && static_cast( !!(expr) ) ) ) // expr here is never evaluated at runtime but it forces the compiler to give it a look // The double negation silences MSVC's C4800 warning, the static_cast forces short-circuit evaluation if the type has overloaded &&. /////////////////////////////////////////////////////////////////////////////// #define INTERNAL_CATCH_IF( macroName, resultDisposition, expr ) \ INTERNAL_CATCH_TEST( macroName, resultDisposition, expr ); \ if( Catch::getResultCapture().lastAssertionPassed() ) /////////////////////////////////////////////////////////////////////////////// #define INTERNAL_CATCH_ELSE( macroName, resultDisposition, expr ) \ INTERNAL_CATCH_TEST( macroName, resultDisposition, expr ); \ if( !Catch::getResultCapture().lastAssertionPassed() ) /////////////////////////////////////////////////////////////////////////////// #define INTERNAL_CATCH_NO_THROW( macroName, resultDisposition, expr ) \ do { \ Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(expr), resultDisposition ); \ try { \ static_cast(expr); \ __catchResult.captureResult( Catch::ResultWas::Ok ); \ } \ catch( ... ) { \ __catchResult.useActiveException( resultDisposition ); \ } \ INTERNAL_CATCH_REACT( __catchResult ) \ } while( Catch::alwaysFalse() ) /////////////////////////////////////////////////////////////////////////////// #define INTERNAL_CATCH_THROWS( macroName, resultDisposition, matcher, expr ) \ do { \ Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(expr), resultDisposition, CATCH_INTERNAL_STRINGIFY(matcher) ); \ if( __catchResult.allowThrows() ) \ try { \ static_cast(expr); \ __catchResult.captureResult( Catch::ResultWas::DidntThrowException ); \ } \ catch( ... ) { \ __catchResult.captureExpectedException( matcher ); \ } \ else \ __catchResult.captureResult( Catch::ResultWas::Ok ); \ INTERNAL_CATCH_REACT( __catchResult ) \ } while( Catch::alwaysFalse() ) /////////////////////////////////////////////////////////////////////////////// #define INTERNAL_CATCH_THROWS_AS( macroName, exceptionType, resultDisposition, expr ) \ do { \ Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(expr) ", " CATCH_INTERNAL_STRINGIFY(exceptionType), resultDisposition ); \ if( __catchResult.allowThrows() ) \ try { \ static_cast(expr); \ __catchResult.captureResult( Catch::ResultWas::DidntThrowException ); \ } \ catch( exceptionType ) { \ __catchResult.captureResult( Catch::ResultWas::Ok ); \ } \ catch( ... ) { \ __catchResult.useActiveException( resultDisposition ); \ } \ else \ __catchResult.captureResult( Catch::ResultWas::Ok ); \ INTERNAL_CATCH_REACT( __catchResult ) \ } while( Catch::alwaysFalse() ) /////////////////////////////////////////////////////////////////////////////// #ifdef CATCH_CONFIG_VARIADIC_MACROS #define INTERNAL_CATCH_MSG( macroName, messageType, resultDisposition, ... ) \ do { \ Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, "", resultDisposition ); \ __catchResult << __VA_ARGS__ + ::Catch::StreamEndStop(); \ __catchResult.captureResult( messageType ); \ INTERNAL_CATCH_REACT( __catchResult ) \ } while( Catch::alwaysFalse() ) #else #define INTERNAL_CATCH_MSG( macroName, messageType, resultDisposition, log ) \ do { \ Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, "", resultDisposition ); \ __catchResult << log + ::Catch::StreamEndStop(); \ __catchResult.captureResult( messageType ); \ INTERNAL_CATCH_REACT( __catchResult ) \ } while( Catch::alwaysFalse() ) #endif /////////////////////////////////////////////////////////////////////////////// #define INTERNAL_CATCH_INFO( macroName, log ) \ Catch::ScopedMessage INTERNAL_CATCH_UNIQUE_NAME( scopedMessage ) = Catch::MessageBuilder( macroName, CATCH_INTERNAL_LINEINFO, Catch::ResultWas::Info ) << log; /////////////////////////////////////////////////////////////////////////////// #define INTERNAL_CHECK_THAT( macroName, matcher, resultDisposition, arg ) \ do { \ Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(arg) ", " CATCH_INTERNAL_STRINGIFY(matcher), resultDisposition ); \ try { \ __catchResult.captureMatch( arg, matcher, CATCH_INTERNAL_STRINGIFY(matcher) ); \ } catch( ... ) { \ __catchResult.useActiveException( resultDisposition | Catch::ResultDisposition::ContinueOnFailure ); \ } \ INTERNAL_CATCH_REACT( __catchResult ) \ } while( Catch::alwaysFalse() ) #endif // TWOBLUECUBES_CATCH_CAPTURE_HPP_INCLUDED catch-1.12.1/include/internal/catch_clara.h000066400000000000000000000020741325474075300205270ustar00rootroot00000000000000/* * Created by Phil on 10/2/2014. * Copyright 2014 Two Blue Cubes Ltd. All rights reserved. * * Distributed under the Boost Software License, Version 1.0. (See accompanying * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) * */ #ifndef TWOBLUECUBES_CATCH_CLARA_H_INCLUDED #define TWOBLUECUBES_CATCH_CLARA_H_INCLUDED // Use Catch's value for console width (store Clara's off to the side, if present) #ifdef CLARA_CONFIG_CONSOLE_WIDTH #define CATCH_TEMP_CLARA_CONFIG_CONSOLE_WIDTH CLARA_CONFIG_CONSOLE_WIDTH #undef CLARA_CONFIG_CONSOLE_WIDTH #endif #define CLARA_CONFIG_CONSOLE_WIDTH CATCH_CONFIG_CONSOLE_WIDTH // Declare Clara inside the Catch namespace #define STITCH_CLARA_OPEN_NAMESPACE namespace Catch { #include "../external/clara.h" #undef STITCH_CLARA_OPEN_NAMESPACE // Restore Clara's value for console width, if present #ifdef CATCH_TEMP_CLARA_CONFIG_CONSOLE_WIDTH #define CLARA_CONFIG_CONSOLE_WIDTH CATCH_TEMP_CLARA_CONFIG_CONSOLE_WIDTH #undef CATCH_TEMP_CLARA_CONFIG_CONSOLE_WIDTH #endif #endif // TWOBLUECUBES_CATCH_CLARA_H_INCLUDED catch-1.12.1/include/internal/catch_commandline.hpp000066400000000000000000000215021325474075300222700ustar00rootroot00000000000000/* * Created by Phil on 02/11/2010. * Copyright 2010 Two Blue Cubes Ltd. All rights reserved. * * Distributed under the Boost Software License, Version 1.0. (See accompanying * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) */ #ifndef TWOBLUECUBES_CATCH_COMMANDLINE_HPP_INCLUDED #define TWOBLUECUBES_CATCH_COMMANDLINE_HPP_INCLUDED #include "catch_config.hpp" #include "catch_common.h" #include "catch_clara.h" #include #include namespace Catch { inline void abortAfterFirst( ConfigData& config ) { config.abortAfter = 1; } inline void abortAfterX( ConfigData& config, int x ) { if( x < 1 ) throw std::runtime_error( "Value after -x or --abortAfter must be greater than zero" ); config.abortAfter = x; } inline void addTestOrTags( ConfigData& config, std::string const& _testSpec ) { config.testsOrTags.push_back( _testSpec ); } inline void addSectionToRun( ConfigData& config, std::string const& sectionName ) { config.sectionsToRun.push_back( sectionName ); } inline void addReporterName( ConfigData& config, std::string const& _reporterName ) { config.reporterNames.push_back( _reporterName ); } inline void addWarning( ConfigData& config, std::string const& _warning ) { if( _warning == "NoAssertions" ) config.warnings = static_cast( config.warnings | WarnAbout::NoAssertions ); else throw std::runtime_error( "Unrecognised warning: '" + _warning + '\'' ); } inline void setOrder( ConfigData& config, std::string const& order ) { if( startsWith( "declared", order ) ) config.runOrder = RunTests::InDeclarationOrder; else if( startsWith( "lexical", order ) ) config.runOrder = RunTests::InLexicographicalOrder; else if( startsWith( "random", order ) ) config.runOrder = RunTests::InRandomOrder; else throw std::runtime_error( "Unrecognised ordering: '" + order + '\'' ); } inline void setRngSeed( ConfigData& config, std::string const& seed ) { if( seed == "time" ) { config.rngSeed = static_cast( std::time(0) ); } else { std::stringstream ss; ss << seed; ss >> config.rngSeed; if( ss.fail() ) throw std::runtime_error( "Argument to --rng-seed should be the word 'time' or a number" ); } } inline void setVerbosity( ConfigData& config, int level ) { // !TBD: accept strings? config.verbosity = static_cast( level ); } inline void setShowDurations( ConfigData& config, bool _showDurations ) { config.showDurations = _showDurations ? ShowDurations::Always : ShowDurations::Never; } inline void setUseColour( ConfigData& config, std::string const& value ) { std::string mode = toLower( value ); if( mode == "yes" ) config.useColour = UseColour::Yes; else if( mode == "no" ) config.useColour = UseColour::No; else if( mode == "auto" ) config.useColour = UseColour::Auto; else throw std::runtime_error( "colour mode must be one of: auto, yes or no" ); } inline void setWaitForKeypress( ConfigData& config, std::string const& keypress ) { std::string keypressLc = toLower( keypress ); if( keypressLc == "start" ) config.waitForKeypress = WaitForKeypress::BeforeStart; else if( keypressLc == "exit" ) config.waitForKeypress = WaitForKeypress::BeforeExit; else if( keypressLc == "both" ) config.waitForKeypress = WaitForKeypress::BeforeStartAndExit; else throw std::runtime_error( "keypress argument must be one of: start, exit or both. '" + keypress + "' not recognised" ); }; inline void forceColour( ConfigData& config ) { config.useColour = UseColour::Yes; } inline void loadTestNamesFromFile( ConfigData& config, std::string const& _filename ) { std::ifstream f( _filename.c_str() ); if( !f.is_open() ) throw std::domain_error( "Unable to load input file: " + _filename ); std::string line; while( std::getline( f, line ) ) { line = trim(line); if( !line.empty() && !startsWith( line, '#' ) ) { if( !startsWith( line, '"' ) ) line = '"' + line + '"'; addTestOrTags( config, line + ',' ); } } } inline Clara::CommandLine makeCommandLineParser() { using namespace Clara; CommandLine cli; cli.bindProcessName( &ConfigData::processName ); cli["-?"]["-h"]["--help"] .describe( "display usage information" ) .bind( &ConfigData::showHelp ); cli["-l"]["--list-tests"] .describe( "list all/matching test cases" ) .bind( &ConfigData::listTests ); cli["-t"]["--list-tags"] .describe( "list all/matching tags" ) .bind( &ConfigData::listTags ); cli["-s"]["--success"] .describe( "include successful tests in output" ) .bind( &ConfigData::showSuccessfulTests ); cli["-b"]["--break"] .describe( "break into debugger on failure" ) .bind( &ConfigData::shouldDebugBreak ); cli["-e"]["--nothrow"] .describe( "skip exception tests" ) .bind( &ConfigData::noThrow ); cli["-i"]["--invisibles"] .describe( "show invisibles (tabs, newlines)" ) .bind( &ConfigData::showInvisibles ); cli["-o"]["--out"] .describe( "output filename" ) .bind( &ConfigData::outputFilename, "filename" ); cli["-r"]["--reporter"] // .placeholder( "name[:filename]" ) .describe( "reporter to use (defaults to console)" ) .bind( &addReporterName, "name" ); cli["-n"]["--name"] .describe( "suite name" ) .bind( &ConfigData::name, "name" ); cli["-a"]["--abort"] .describe( "abort at first failure" ) .bind( &abortAfterFirst ); cli["-x"]["--abortx"] .describe( "abort after x failures" ) .bind( &abortAfterX, "no. failures" ); cli["-w"]["--warn"] .describe( "enable warnings" ) .bind( &addWarning, "warning name" ); // - needs updating if reinstated // cli.into( &setVerbosity ) // .describe( "level of verbosity (0=no output)" ) // .shortOpt( "v") // .longOpt( "verbosity" ) // .placeholder( "level" ); cli[_] .describe( "which test or tests to use" ) .bind( &addTestOrTags, "test name, pattern or tags" ); cli["-d"]["--durations"] .describe( "show test durations" ) .bind( &setShowDurations, "yes|no" ); cli["-f"]["--input-file"] .describe( "load test names to run from a file" ) .bind( &loadTestNamesFromFile, "filename" ); cli["-#"]["--filenames-as-tags"] .describe( "adds a tag for the filename" ) .bind( &ConfigData::filenamesAsTags ); cli["-c"]["--section"] .describe( "specify section to run" ) .bind( &addSectionToRun, "section name" ); // Less common commands which don't have a short form cli["--list-test-names-only"] .describe( "list all/matching test cases names only" ) .bind( &ConfigData::listTestNamesOnly ); cli["--list-extra-info"] .describe( "list all/matching test cases with more info" ) .bind( &ConfigData::listExtraInfo ); cli["--list-reporters"] .describe( "list all reporters" ) .bind( &ConfigData::listReporters ); cli["--order"] .describe( "test case order (defaults to decl)" ) .bind( &setOrder, "decl|lex|rand" ); cli["--rng-seed"] .describe( "set a specific seed for random numbers" ) .bind( &setRngSeed, "'time'|number" ); cli["--force-colour"] .describe( "force colourised output (deprecated)" ) .bind( &forceColour ); cli["--use-colour"] .describe( "should output be colourised" ) .bind( &setUseColour, "yes|no" ); cli["--libidentify"] .describe( "report name and version according to libidentify standard" ) .bind( &ConfigData::libIdentify ); cli["--wait-for-keypress"] .describe( "waits for a keypress before exiting" ) .bind( &setWaitForKeypress, "start|exit|both" ); return cli; } } // end namespace Catch #endif // TWOBLUECUBES_CATCH_COMMANDLINE_HPP_INCLUDED catch-1.12.1/include/internal/catch_common.h000066400000000000000000000117121325474075300207340ustar00rootroot00000000000000/* * Created by Phil on 29/10/2010. * Copyright 2010 Two Blue Cubes Ltd. All rights reserved. * * Distributed under the Boost Software License, Version 1.0. (See accompanying * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) */ #ifndef TWOBLUECUBES_CATCH_COMMON_H_INCLUDED #define TWOBLUECUBES_CATCH_COMMON_H_INCLUDED #include "catch_compiler_capabilities.h" #define INTERNAL_CATCH_UNIQUE_NAME_LINE2( name, line ) name##line #define INTERNAL_CATCH_UNIQUE_NAME_LINE( name, line ) INTERNAL_CATCH_UNIQUE_NAME_LINE2( name, line ) #ifdef CATCH_CONFIG_COUNTER # define INTERNAL_CATCH_UNIQUE_NAME( name ) INTERNAL_CATCH_UNIQUE_NAME_LINE( name, __COUNTER__ ) #else # define INTERNAL_CATCH_UNIQUE_NAME( name ) INTERNAL_CATCH_UNIQUE_NAME_LINE( name, __LINE__ ) #endif #define INTERNAL_CATCH_STRINGIFY2( expr ) #expr #define INTERNAL_CATCH_STRINGIFY( expr ) INTERNAL_CATCH_STRINGIFY2( expr ) #include #include namespace Catch { struct IConfig; struct CaseSensitive { enum Choice { Yes, No }; }; class NonCopyable { #ifdef CATCH_CONFIG_CPP11_GENERATED_METHODS NonCopyable( NonCopyable const& ) = delete; NonCopyable( NonCopyable && ) = delete; NonCopyable& operator = ( NonCopyable const& ) = delete; NonCopyable& operator = ( NonCopyable && ) = delete; #else NonCopyable( NonCopyable const& info ); NonCopyable& operator = ( NonCopyable const& ); #endif protected: NonCopyable() {} virtual ~NonCopyable(); }; class SafeBool { public: typedef void (SafeBool::*type)() const; static type makeSafe( bool value ) { return value ? &SafeBool::trueValue : 0; } private: void trueValue() const {} }; template void deleteAll( ContainerT& container ) { typename ContainerT::const_iterator it = container.begin(); typename ContainerT::const_iterator itEnd = container.end(); for(; it != itEnd; ++it ) delete *it; } template void deleteAllValues( AssociativeContainerT& container ) { typename AssociativeContainerT::const_iterator it = container.begin(); typename AssociativeContainerT::const_iterator itEnd = container.end(); for(; it != itEnd; ++it ) delete it->second; } bool startsWith( std::string const& s, std::string const& prefix ); bool startsWith( std::string const& s, char prefix ); bool endsWith( std::string const& s, std::string const& suffix ); bool endsWith( std::string const& s, char suffix ); bool contains( std::string const& s, std::string const& infix ); void toLowerInPlace( std::string& s ); std::string toLower( std::string const& s ); std::string trim( std::string const& str ); bool replaceInPlace( std::string& str, std::string const& replaceThis, std::string const& withThis ); struct pluralise { pluralise( std::size_t count, std::string const& label ); friend std::ostream& operator << ( std::ostream& os, pluralise const& pluraliser ); std::size_t m_count; std::string m_label; }; struct SourceLineInfo { SourceLineInfo(); SourceLineInfo( char const* _file, std::size_t _line ); # ifdef CATCH_CONFIG_CPP11_GENERATED_METHODS SourceLineInfo(SourceLineInfo const& other) = default; SourceLineInfo( SourceLineInfo && ) = default; SourceLineInfo& operator = ( SourceLineInfo const& ) = default; SourceLineInfo& operator = ( SourceLineInfo && ) = default; # endif bool empty() const; bool operator == ( SourceLineInfo const& other ) const; bool operator < ( SourceLineInfo const& other ) const; char const* file; std::size_t line; }; std::ostream& operator << ( std::ostream& os, SourceLineInfo const& info ); // This is just here to avoid compiler warnings with macro constants and boolean literals inline bool isTrue( bool value ){ return value; } inline bool alwaysTrue() { return true; } inline bool alwaysFalse() { return false; } void throwLogicError( std::string const& message, SourceLineInfo const& locationInfo ); void seedRng( IConfig const& config ); unsigned int rngSeed(); // Use this in variadic streaming macros to allow // >> +StreamEndStop // as well as // >> stuff +StreamEndStop struct StreamEndStop { std::string operator+() { return std::string(); } }; template T const& operator + ( T const& value, StreamEndStop ) { return value; } } #define CATCH_INTERNAL_LINEINFO ::Catch::SourceLineInfo( __FILE__, static_cast( __LINE__ ) ) #define CATCH_INTERNAL_ERROR( msg ) ::Catch::throwLogicError( msg, CATCH_INTERNAL_LINEINFO ); #endif // TWOBLUECUBES_CATCH_COMMON_H_INCLUDED catch-1.12.1/include/internal/catch_common.hpp000066400000000000000000000101471325474075300212750ustar00rootroot00000000000000/* * Created by Phil on 27/11/2013. * Copyright 2013 Two Blue Cubes Ltd. All rights reserved. * * Distributed under the Boost Software License, Version 1.0. (See accompanying * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) */ #ifndef TWOBLUECUBES_CATCH_COMMON_HPP_INCLUDED #define TWOBLUECUBES_CATCH_COMMON_HPP_INCLUDED #include "catch_common.h" #include #include namespace Catch { bool startsWith( std::string const& s, std::string const& prefix ) { return s.size() >= prefix.size() && std::equal(prefix.begin(), prefix.end(), s.begin()); } bool startsWith( std::string const& s, char prefix ) { return !s.empty() && s[0] == prefix; } bool endsWith( std::string const& s, std::string const& suffix ) { return s.size() >= suffix.size() && std::equal(suffix.rbegin(), suffix.rend(), s.rbegin()); } bool endsWith( std::string const& s, char suffix ) { return !s.empty() && s[s.size()-1] == suffix; } bool contains( std::string const& s, std::string const& infix ) { return s.find( infix ) != std::string::npos; } char toLowerCh(char c) { return static_cast( std::tolower( c ) ); } void toLowerInPlace( std::string& s ) { std::transform( s.begin(), s.end(), s.begin(), toLowerCh ); } std::string toLower( std::string const& s ) { std::string lc = s; toLowerInPlace( lc ); return lc; } std::string trim( std::string const& str ) { static char const* whitespaceChars = "\n\r\t "; std::string::size_type start = str.find_first_not_of( whitespaceChars ); std::string::size_type end = str.find_last_not_of( whitespaceChars ); return start != std::string::npos ? str.substr( start, 1+end-start ) : std::string(); } bool replaceInPlace( std::string& str, std::string const& replaceThis, std::string const& withThis ) { bool replaced = false; std::size_t i = str.find( replaceThis ); while( i != std::string::npos ) { replaced = true; str = str.substr( 0, i ) + withThis + str.substr( i+replaceThis.size() ); if( i < str.size()-withThis.size() ) i = str.find( replaceThis, i+withThis.size() ); else i = std::string::npos; } return replaced; } pluralise::pluralise( std::size_t count, std::string const& label ) : m_count( count ), m_label( label ) {} std::ostream& operator << ( std::ostream& os, pluralise const& pluraliser ) { os << pluraliser.m_count << ' ' << pluraliser.m_label; if( pluraliser.m_count != 1 ) os << 's'; return os; } SourceLineInfo::SourceLineInfo() : file(""), line( 0 ){} SourceLineInfo::SourceLineInfo( char const* _file, std::size_t _line ) : file( _file ), line( _line ) {} bool SourceLineInfo::empty() const { return file[0] == '\0'; } bool SourceLineInfo::operator == ( SourceLineInfo const& other ) const { return line == other.line && (file == other.file || std::strcmp(file, other.file) == 0); } bool SourceLineInfo::operator < ( SourceLineInfo const& other ) const { return line < other.line || ( line == other.line && (std::strcmp(file, other.file) < 0)); } void seedRng( IConfig const& config ) { if( config.rngSeed() != 0 ) std::srand( config.rngSeed() ); } unsigned int rngSeed() { return getCurrentContext().getConfig()->rngSeed(); } std::ostream& operator << ( std::ostream& os, SourceLineInfo const& info ) { #ifndef __GNUG__ os << info.file << '(' << info.line << ')'; #else os << info.file << ':' << info.line; #endif return os; } void throwLogicError( std::string const& message, SourceLineInfo const& locationInfo ) { std::ostringstream oss; oss << locationInfo << ": Internal Catch error: '" << message << '\''; if( alwaysTrue() ) throw std::logic_error( oss.str() ); } } #endif // TWOBLUECUBES_CATCH_COMMON_HPP_INCLUDED catch-1.12.1/include/internal/catch_compiler_capabilities.h000066400000000000000000000265351325474075300240000ustar00rootroot00000000000000/* * Created by Phil on 15/04/2013. * Copyright 2013 Two Blue Cubes Ltd. All rights reserved. * * Distributed under the Boost Software License, Version 1.0. (See accompanying * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) */ #ifndef TWOBLUECUBES_CATCH_COMPILER_CAPABILITIES_HPP_INCLUDED #define TWOBLUECUBES_CATCH_COMPILER_CAPABILITIES_HPP_INCLUDED // Detect a number of compiler features - mostly C++11/14 conformance - by compiler // The following features are defined: // // CATCH_CONFIG_CPP11_NULLPTR : is nullptr supported? // CATCH_CONFIG_CPP11_NOEXCEPT : is noexcept supported? // CATCH_CONFIG_CPP11_GENERATED_METHODS : The delete and default keywords for compiler generated methods // CATCH_CONFIG_CPP11_IS_ENUM : std::is_enum is supported? // CATCH_CONFIG_CPP11_TUPLE : std::tuple is supported // CATCH_CONFIG_CPP11_LONG_LONG : is long long supported? // CATCH_CONFIG_CPP11_OVERRIDE : is override supported? // CATCH_CONFIG_CPP11_UNIQUE_PTR : is unique_ptr supported (otherwise use auto_ptr) // CATCH_CONFIG_CPP11_SHUFFLE : is std::shuffle supported? // CATCH_CONFIG_CPP11_TYPE_TRAITS : are type_traits and enable_if supported? // CATCH_CONFIG_CPP11_OR_GREATER : Is C++11 supported? // CATCH_CONFIG_VARIADIC_MACROS : are variadic macros supported? // CATCH_CONFIG_COUNTER : is the __COUNTER__ macro supported? // CATCH_CONFIG_WINDOWS_SEH : is Windows SEH supported? // CATCH_CONFIG_POSIX_SIGNALS : are POSIX signals supported? // **************** // Note to maintainers: if new toggles are added please document them // in configuration.md, too // **************** // In general each macro has a _NO_ form // (e.g. CATCH_CONFIG_CPP11_NO_NULLPTR) which disables the feature. // Many features, at point of detection, define an _INTERNAL_ macro, so they // can be combined, en-mass, with the _NO_ forms later. // All the C++11 features can be disabled with CATCH_CONFIG_NO_CPP11 #ifdef __cplusplus # if __cplusplus >= 201103L # define CATCH_CPP11_OR_GREATER # endif # if __cplusplus >= 201402L # define CATCH_CPP14_OR_GREATER # endif #endif #ifdef __clang__ # if __has_feature(cxx_nullptr) # define CATCH_INTERNAL_CONFIG_CPP11_NULLPTR # endif # if __has_feature(cxx_noexcept) # define CATCH_INTERNAL_CONFIG_CPP11_NOEXCEPT # endif # if defined(CATCH_CPP11_OR_GREATER) # define CATCH_INTERNAL_SUPPRESS_ETD_WARNINGS \ _Pragma( "clang diagnostic push" ) \ _Pragma( "clang diagnostic ignored \"-Wexit-time-destructors\"" ) # define CATCH_INTERNAL_UNSUPPRESS_ETD_WARNINGS \ _Pragma( "clang diagnostic pop" ) # define CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS \ _Pragma( "clang diagnostic push" ) \ _Pragma( "clang diagnostic ignored \"-Wparentheses\"" ) # define CATCH_INTERNAL_UNSUPPRESS_PARENTHESES_WARNINGS \ _Pragma( "clang diagnostic pop" ) # endif #endif // __clang__ //////////////////////////////////////////////////////////////////////////////// // We know some environments not to support full POSIX signals #if defined(__CYGWIN__) || defined(__QNX__) # if !defined(CATCH_CONFIG_POSIX_SIGNALS) # define CATCH_INTERNAL_CONFIG_NO_POSIX_SIGNALS # endif #endif #ifdef __OS400__ # define CATCH_INTERNAL_CONFIG_NO_POSIX_SIGNALS # define CATCH_CONFIG_COLOUR_NONE #endif //////////////////////////////////////////////////////////////////////////////// // Cygwin #ifdef __CYGWIN__ // Required for some versions of Cygwin to declare gettimeofday // see: http://stackoverflow.com/questions/36901803/gettimeofday-not-declared-in-this-scope-cygwin # define _BSD_SOURCE #endif // __CYGWIN__ //////////////////////////////////////////////////////////////////////////////// // Borland #ifdef __BORLANDC__ #endif // __BORLANDC__ //////////////////////////////////////////////////////////////////////////////// // EDG #ifdef __EDG_VERSION__ #endif // __EDG_VERSION__ //////////////////////////////////////////////////////////////////////////////// // Digital Mars #ifdef __DMC__ #endif // __DMC__ //////////////////////////////////////////////////////////////////////////////// // GCC #ifdef __GNUC__ # if __GNUC__ == 4 && __GNUC_MINOR__ >= 6 && defined(__GXX_EXPERIMENTAL_CXX0X__) # define CATCH_INTERNAL_CONFIG_CPP11_NULLPTR # endif // - otherwise more recent versions define __cplusplus >= 201103L // and will get picked up below #endif // __GNUC__ //////////////////////////////////////////////////////////////////////////////// // Visual C++ #ifdef _MSC_VER #define CATCH_INTERNAL_CONFIG_WINDOWS_SEH #if (_MSC_VER >= 1600) # define CATCH_INTERNAL_CONFIG_CPP11_NULLPTR # define CATCH_INTERNAL_CONFIG_CPP11_UNIQUE_PTR #endif #if (_MSC_VER >= 1900 ) // (VC++ 13 (VS2015)) #define CATCH_INTERNAL_CONFIG_CPP11_NOEXCEPT #define CATCH_INTERNAL_CONFIG_CPP11_GENERATED_METHODS #define CATCH_INTERNAL_CONFIG_CPP11_SHUFFLE #define CATCH_INTERNAL_CONFIG_CPP11_TYPE_TRAITS #endif #endif // _MSC_VER //////////////////////////////////////////////////////////////////////////////// // Use variadic macros if the compiler supports them #if ( defined _MSC_VER && _MSC_VER > 1400 && !defined __EDGE__) || \ ( defined __WAVE__ && __WAVE_HAS_VARIADICS ) || \ ( defined __GNUC__ && __GNUC__ >= 3 ) || \ ( !defined __cplusplus && __STDC_VERSION__ >= 199901L || __cplusplus >= 201103L ) #define CATCH_INTERNAL_CONFIG_VARIADIC_MACROS #endif // Use __COUNTER__ if the compiler supports it #if ( defined _MSC_VER && _MSC_VER >= 1300 ) || \ ( defined __GNUC__ && ( __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3 )) ) || \ ( defined __clang__ && __clang_major__ >= 3 ) // Use of __COUNTER__ is suppressed during code analysis in CLion/AppCode 2017.2.x and former, // because __COUNTER__ is not properly handled by it. // This does not affect compilation #if ( !defined __JETBRAINS_IDE__ || __JETBRAINS_IDE__ >= 20170300L ) #define CATCH_INTERNAL_CONFIG_COUNTER #endif #endif //////////////////////////////////////////////////////////////////////////////// // C++ language feature support // catch all support for C++11 #if defined(CATCH_CPP11_OR_GREATER) # if !defined(CATCH_INTERNAL_CONFIG_CPP11_NULLPTR) # define CATCH_INTERNAL_CONFIG_CPP11_NULLPTR # endif # ifndef CATCH_INTERNAL_CONFIG_CPP11_NOEXCEPT # define CATCH_INTERNAL_CONFIG_CPP11_NOEXCEPT # endif # ifndef CATCH_INTERNAL_CONFIG_CPP11_GENERATED_METHODS # define CATCH_INTERNAL_CONFIG_CPP11_GENERATED_METHODS # endif # ifndef CATCH_INTERNAL_CONFIG_CPP11_IS_ENUM # define CATCH_INTERNAL_CONFIG_CPP11_IS_ENUM # endif # ifndef CATCH_INTERNAL_CONFIG_CPP11_TUPLE # define CATCH_INTERNAL_CONFIG_CPP11_TUPLE # endif # ifndef CATCH_INTERNAL_CONFIG_VARIADIC_MACROS # define CATCH_INTERNAL_CONFIG_VARIADIC_MACROS # endif # if !defined(CATCH_INTERNAL_CONFIG_CPP11_LONG_LONG) # define CATCH_INTERNAL_CONFIG_CPP11_LONG_LONG # endif # if !defined(CATCH_INTERNAL_CONFIG_CPP11_OVERRIDE) # define CATCH_INTERNAL_CONFIG_CPP11_OVERRIDE # endif # if !defined(CATCH_INTERNAL_CONFIG_CPP11_UNIQUE_PTR) # define CATCH_INTERNAL_CONFIG_CPP11_UNIQUE_PTR # endif # if !defined(CATCH_INTERNAL_CONFIG_CPP11_SHUFFLE) # define CATCH_INTERNAL_CONFIG_CPP11_SHUFFLE # endif # if !defined(CATCH_INTERNAL_CONFIG_CPP11_TYPE_TRAITS) # define CATCH_INTERNAL_CONFIG_CPP11_TYPE_TRAITS # endif #endif // __cplusplus >= 201103L // Now set the actual defines based on the above + anything the user has configured #if defined(CATCH_INTERNAL_CONFIG_CPP11_NULLPTR) && !defined(CATCH_CONFIG_CPP11_NO_NULLPTR) && !defined(CATCH_CONFIG_CPP11_NULLPTR) && !defined(CATCH_CONFIG_NO_CPP11) # define CATCH_CONFIG_CPP11_NULLPTR #endif #if defined(CATCH_INTERNAL_CONFIG_CPP11_NOEXCEPT) && !defined(CATCH_CONFIG_CPP11_NO_NOEXCEPT) && !defined(CATCH_CONFIG_CPP11_NOEXCEPT) && !defined(CATCH_CONFIG_NO_CPP11) # define CATCH_CONFIG_CPP11_NOEXCEPT #endif #if defined(CATCH_INTERNAL_CONFIG_CPP11_GENERATED_METHODS) && !defined(CATCH_CONFIG_CPP11_NO_GENERATED_METHODS) && !defined(CATCH_CONFIG_CPP11_GENERATED_METHODS) && !defined(CATCH_CONFIG_NO_CPP11) # define CATCH_CONFIG_CPP11_GENERATED_METHODS #endif #if defined(CATCH_INTERNAL_CONFIG_CPP11_IS_ENUM) && !defined(CATCH_CONFIG_CPP11_NO_IS_ENUM) && !defined(CATCH_CONFIG_CPP11_IS_ENUM) && !defined(CATCH_CONFIG_NO_CPP11) # define CATCH_CONFIG_CPP11_IS_ENUM #endif #if defined(CATCH_INTERNAL_CONFIG_CPP11_TUPLE) && !defined(CATCH_CONFIG_CPP11_NO_TUPLE) && !defined(CATCH_CONFIG_CPP11_TUPLE) && !defined(CATCH_CONFIG_NO_CPP11) # define CATCH_CONFIG_CPP11_TUPLE #endif #if defined(CATCH_INTERNAL_CONFIG_VARIADIC_MACROS) && !defined(CATCH_CONFIG_NO_VARIADIC_MACROS) && !defined(CATCH_CONFIG_VARIADIC_MACROS) # define CATCH_CONFIG_VARIADIC_MACROS #endif #if defined(CATCH_INTERNAL_CONFIG_CPP11_LONG_LONG) && !defined(CATCH_CONFIG_CPP11_NO_LONG_LONG) && !defined(CATCH_CONFIG_CPP11_LONG_LONG) && !defined(CATCH_CONFIG_NO_CPP11) # define CATCH_CONFIG_CPP11_LONG_LONG #endif #if defined(CATCH_INTERNAL_CONFIG_CPP11_OVERRIDE) && !defined(CATCH_CONFIG_CPP11_NO_OVERRIDE) && !defined(CATCH_CONFIG_CPP11_OVERRIDE) && !defined(CATCH_CONFIG_NO_CPP11) # define CATCH_CONFIG_CPP11_OVERRIDE #endif #if defined(CATCH_INTERNAL_CONFIG_CPP11_UNIQUE_PTR) && !defined(CATCH_CONFIG_CPP11_NO_UNIQUE_PTR) && !defined(CATCH_CONFIG_CPP11_UNIQUE_PTR) && !defined(CATCH_CONFIG_NO_CPP11) # define CATCH_CONFIG_CPP11_UNIQUE_PTR #endif #if defined(CATCH_INTERNAL_CONFIG_COUNTER) && !defined(CATCH_CONFIG_NO_COUNTER) && !defined(CATCH_CONFIG_COUNTER) # define CATCH_CONFIG_COUNTER #endif #if defined(CATCH_INTERNAL_CONFIG_CPP11_SHUFFLE) && !defined(CATCH_CONFIG_CPP11_NO_SHUFFLE) && !defined(CATCH_CONFIG_CPP11_SHUFFLE) && !defined(CATCH_CONFIG_NO_CPP11) # define CATCH_CONFIG_CPP11_SHUFFLE #endif # if defined(CATCH_INTERNAL_CONFIG_CPP11_TYPE_TRAITS) && !defined(CATCH_CONFIG_CPP11_NO_TYPE_TRAITS) && !defined(CATCH_CONFIG_CPP11_TYPE_TRAITS) && !defined(CATCH_CONFIG_NO_CPP11) # define CATCH_CONFIG_CPP11_TYPE_TRAITS # endif #if defined(CATCH_INTERNAL_CONFIG_WINDOWS_SEH) && !defined(CATCH_CONFIG_NO_WINDOWS_SEH) && !defined(CATCH_CONFIG_WINDOWS_SEH) # define CATCH_CONFIG_WINDOWS_SEH #endif // This is set by default, because we assume that unix compilers are posix-signal-compatible by default. #if !defined(CATCH_INTERNAL_CONFIG_NO_POSIX_SIGNALS) && !defined(CATCH_CONFIG_NO_POSIX_SIGNALS) && !defined(CATCH_CONFIG_POSIX_SIGNALS) # define CATCH_CONFIG_POSIX_SIGNALS #endif #if !defined(CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS) # define CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS # define CATCH_INTERNAL_UNSUPPRESS_PARENTHESES_WARNINGS #endif #if !defined(CATCH_INTERNAL_SUPPRESS_ETD_WARNINGS) # define CATCH_INTERNAL_SUPPRESS_ETD_WARNINGS # define CATCH_INTERNAL_UNSUPPRESS_ETD_WARNINGS #endif // noexcept support: #if defined(CATCH_CONFIG_CPP11_NOEXCEPT) && !defined(CATCH_NOEXCEPT) # define CATCH_NOEXCEPT noexcept # define CATCH_NOEXCEPT_IS(x) noexcept(x) #else # define CATCH_NOEXCEPT throw() # define CATCH_NOEXCEPT_IS(x) #endif // nullptr support #ifdef CATCH_CONFIG_CPP11_NULLPTR # define CATCH_NULL nullptr #else # define CATCH_NULL NULL #endif // override support #ifdef CATCH_CONFIG_CPP11_OVERRIDE # define CATCH_OVERRIDE override #else # define CATCH_OVERRIDE #endif // unique_ptr support #ifdef CATCH_CONFIG_CPP11_UNIQUE_PTR # define CATCH_AUTO_PTR( T ) std::unique_ptr #else # define CATCH_AUTO_PTR( T ) std::auto_ptr #endif #endif // TWOBLUECUBES_CATCH_COMPILER_CAPABILITIES_HPP_INCLUDED catch-1.12.1/include/internal/catch_config.hpp000066400000000000000000000134611325474075300212540ustar00rootroot00000000000000/* * Created by Phil on 08/11/2010. * Copyright 2010 Two Blue Cubes Ltd. All rights reserved. * * Distributed under the Boost Software License, Version 1.0. (See accompanying * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) */ #ifndef TWOBLUECUBES_CATCH_CONFIG_HPP_INCLUDED #define TWOBLUECUBES_CATCH_CONFIG_HPP_INCLUDED #include "catch_test_spec_parser.hpp" #include "catch_context.h" #include "catch_interfaces_config.h" #include "catch_stream.h" #include #include #include #include #ifndef CATCH_CONFIG_CONSOLE_WIDTH #define CATCH_CONFIG_CONSOLE_WIDTH 80 #endif namespace Catch { struct ConfigData { ConfigData() : listTests( false ), listTags( false ), listReporters( false ), listTestNamesOnly( false ), listExtraInfo( false ), showSuccessfulTests( false ), shouldDebugBreak( false ), noThrow( false ), showHelp( false ), showInvisibles( false ), filenamesAsTags( false ), libIdentify( false ), abortAfter( -1 ), rngSeed( 0 ), verbosity( Verbosity::Normal ), warnings( WarnAbout::Nothing ), showDurations( ShowDurations::DefaultForReporter ), runOrder( RunTests::InDeclarationOrder ), useColour( UseColour::Auto ), waitForKeypress( WaitForKeypress::Never ) {} bool listTests; bool listTags; bool listReporters; bool listTestNamesOnly; bool listExtraInfo; bool showSuccessfulTests; bool shouldDebugBreak; bool noThrow; bool showHelp; bool showInvisibles; bool filenamesAsTags; bool libIdentify; int abortAfter; unsigned int rngSeed; Verbosity::Level verbosity; WarnAbout::What warnings; ShowDurations::OrNot showDurations; RunTests::InWhatOrder runOrder; UseColour::YesOrNo useColour; WaitForKeypress::When waitForKeypress; std::string outputFilename; std::string name; std::string processName; std::vector reporterNames; std::vector testsOrTags; std::vector sectionsToRun; }; class Config : public SharedImpl { private: Config( Config const& other ); Config& operator = ( Config const& other ); virtual void dummy(); public: Config() {} Config( ConfigData const& data ) : m_data( data ), m_stream( openStream() ) { if( !data.testsOrTags.empty() ) { TestSpecParser parser( ITagAliasRegistry::get() ); for( std::size_t i = 0; i < data.testsOrTags.size(); ++i ) parser.parse( data.testsOrTags[i] ); m_testSpec = parser.testSpec(); } } virtual ~Config() {} std::string const& getFilename() const { return m_data.outputFilename ; } bool listTests() const { return m_data.listTests; } bool listTestNamesOnly() const { return m_data.listTestNamesOnly; } bool listTags() const { return m_data.listTags; } bool listReporters() const { return m_data.listReporters; } bool listExtraInfo() const { return m_data.listExtraInfo; } std::string getProcessName() const { return m_data.processName; } std::vector const& getReporterNames() const { return m_data.reporterNames; } std::vector const& getSectionsToRun() const CATCH_OVERRIDE { return m_data.sectionsToRun; } virtual TestSpec const& testSpec() const CATCH_OVERRIDE { return m_testSpec; } bool showHelp() const { return m_data.showHelp; } // IConfig interface virtual bool allowThrows() const CATCH_OVERRIDE { return !m_data.noThrow; } virtual std::ostream& stream() const CATCH_OVERRIDE { return m_stream->stream(); } virtual std::string name() const CATCH_OVERRIDE { return m_data.name.empty() ? m_data.processName : m_data.name; } virtual bool includeSuccessfulResults() const CATCH_OVERRIDE { return m_data.showSuccessfulTests; } virtual bool warnAboutMissingAssertions() const CATCH_OVERRIDE { return m_data.warnings & WarnAbout::NoAssertions; } virtual ShowDurations::OrNot showDurations() const CATCH_OVERRIDE { return m_data.showDurations; } virtual RunTests::InWhatOrder runOrder() const CATCH_OVERRIDE { return m_data.runOrder; } virtual unsigned int rngSeed() const CATCH_OVERRIDE { return m_data.rngSeed; } virtual UseColour::YesOrNo useColour() const CATCH_OVERRIDE { return m_data.useColour; } virtual bool shouldDebugBreak() const CATCH_OVERRIDE { return m_data.shouldDebugBreak; } virtual int abortAfter() const CATCH_OVERRIDE { return m_data.abortAfter; } virtual bool showInvisibles() const CATCH_OVERRIDE { return m_data.showInvisibles; } private: IStream const* openStream() { if( m_data.outputFilename.empty() ) return new CoutStream(); else if( m_data.outputFilename[0] == '%' ) { if( m_data.outputFilename == "%debug" ) return new DebugOutStream(); else throw std::domain_error( "Unrecognised stream: " + m_data.outputFilename ); } else return new FileStream( m_data.outputFilename ); } ConfigData m_data; CATCH_AUTO_PTR( IStream const ) m_stream; TestSpec m_testSpec; }; } // end namespace Catch #endif // TWOBLUECUBES_CATCH_CONFIG_HPP_INCLUDED catch-1.12.1/include/internal/catch_console_colour.hpp000066400000000000000000000032401325474075300230260ustar00rootroot00000000000000/* * Created by Phil on 25/2/2012. * Copyright 2012 Two Blue Cubes Ltd. All rights reserved. * * Distributed under the Boost Software License, Version 1.0. (See accompanying * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) */ #ifndef TWOBLUECUBES_CATCH_CONSOLE_COLOUR_HPP_INCLUDED #define TWOBLUECUBES_CATCH_CONSOLE_COLOUR_HPP_INCLUDED #include "catch_common.h" namespace Catch { struct Colour { enum Code { None = 0, White, Red, Green, Blue, Cyan, Yellow, Grey, Bright = 0x10, BrightRed = Bright | Red, BrightGreen = Bright | Green, LightGrey = Bright | Grey, BrightWhite = Bright | White, // By intention FileName = LightGrey, Warning = Yellow, ResultError = BrightRed, ResultSuccess = BrightGreen, ResultExpectedFailure = Warning, Error = BrightRed, Success = Green, OriginalExpression = Cyan, ReconstructedExpression = Yellow, SecondaryText = LightGrey, Headers = White }; // Use constructed object for RAII guard Colour( Code _colourCode ); Colour( Colour const& other ); ~Colour(); // Use static method for one-shot changes static void use( Code _colourCode ); private: bool m_moved; }; inline std::ostream& operator << ( std::ostream& os, Colour const& ) { return os; } } // end namespace Catch #endif // TWOBLUECUBES_CATCH_CONSOLE_COLOUR_HPP_INCLUDED catch-1.12.1/include/internal/catch_console_colour_impl.hpp000066400000000000000000000160701325474075300240540ustar00rootroot00000000000000/* * Created by Phil on 25/2/2012. * Copyright 2012 Two Blue Cubes Ltd. All rights reserved. * * Distributed under the Boost Software License, Version 1.0. (See accompanying * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) */ #ifndef TWOBLUECUBES_CATCH_CONSOLE_COLOUR_IMPL_HPP_INCLUDED #define TWOBLUECUBES_CATCH_CONSOLE_COLOUR_IMPL_HPP_INCLUDED #include "catch_console_colour.hpp" #include "catch_errno_guard.hpp" namespace Catch { namespace { struct IColourImpl { virtual ~IColourImpl() {} virtual void use( Colour::Code _colourCode ) = 0; }; struct NoColourImpl : IColourImpl { void use( Colour::Code ) {} static IColourImpl* instance() { static NoColourImpl s_instance; return &s_instance; } }; } // anon namespace } // namespace Catch #if !defined( CATCH_CONFIG_COLOUR_NONE ) && !defined( CATCH_CONFIG_COLOUR_WINDOWS ) && !defined( CATCH_CONFIG_COLOUR_ANSI ) # ifdef CATCH_PLATFORM_WINDOWS # define CATCH_CONFIG_COLOUR_WINDOWS # else # define CATCH_CONFIG_COLOUR_ANSI # endif #endif #if defined ( CATCH_CONFIG_COLOUR_WINDOWS ) ///////////////////////////////////////// #include "catch_windows_h_proxy.h" namespace Catch { namespace { class Win32ColourImpl : public IColourImpl { public: Win32ColourImpl() : stdoutHandle( GetStdHandle(STD_OUTPUT_HANDLE) ) { CONSOLE_SCREEN_BUFFER_INFO csbiInfo; GetConsoleScreenBufferInfo( stdoutHandle, &csbiInfo ); originalForegroundAttributes = csbiInfo.wAttributes & ~( BACKGROUND_GREEN | BACKGROUND_RED | BACKGROUND_BLUE | BACKGROUND_INTENSITY ); originalBackgroundAttributes = csbiInfo.wAttributes & ~( FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_BLUE | FOREGROUND_INTENSITY ); } virtual void use( Colour::Code _colourCode ) { switch( _colourCode ) { case Colour::None: return setTextAttribute( originalForegroundAttributes ); case Colour::White: return setTextAttribute( FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_BLUE ); case Colour::Red: return setTextAttribute( FOREGROUND_RED ); case Colour::Green: return setTextAttribute( FOREGROUND_GREEN ); case Colour::Blue: return setTextAttribute( FOREGROUND_BLUE ); case Colour::Cyan: return setTextAttribute( FOREGROUND_BLUE | FOREGROUND_GREEN ); case Colour::Yellow: return setTextAttribute( FOREGROUND_RED | FOREGROUND_GREEN ); case Colour::Grey: return setTextAttribute( 0 ); case Colour::LightGrey: return setTextAttribute( FOREGROUND_INTENSITY ); case Colour::BrightRed: return setTextAttribute( FOREGROUND_INTENSITY | FOREGROUND_RED ); case Colour::BrightGreen: return setTextAttribute( FOREGROUND_INTENSITY | FOREGROUND_GREEN ); case Colour::BrightWhite: return setTextAttribute( FOREGROUND_INTENSITY | FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_BLUE ); case Colour::Bright: throw std::logic_error( "not a colour" ); } } private: void setTextAttribute( WORD _textAttribute ) { SetConsoleTextAttribute( stdoutHandle, _textAttribute | originalBackgroundAttributes ); } HANDLE stdoutHandle; WORD originalForegroundAttributes; WORD originalBackgroundAttributes; }; IColourImpl* platformColourInstance() { static Win32ColourImpl s_instance; Ptr config = getCurrentContext().getConfig(); UseColour::YesOrNo colourMode = config ? config->useColour() : UseColour::Auto; if( colourMode == UseColour::Auto ) colourMode = !isDebuggerActive() ? UseColour::Yes : UseColour::No; return colourMode == UseColour::Yes ? &s_instance : NoColourImpl::instance(); } } // end anon namespace } // end namespace Catch #elif defined( CATCH_CONFIG_COLOUR_ANSI ) ////////////////////////////////////// #include namespace Catch { namespace { // use POSIX/ ANSI console terminal codes // Thanks to Adam Strzelecki for original contribution // (http://github.com/nanoant) // https://github.com/philsquared/Catch/pull/131 class PosixColourImpl : public IColourImpl { public: virtual void use( Colour::Code _colourCode ) { switch( _colourCode ) { case Colour::None: case Colour::White: return setColour( "[0m" ); case Colour::Red: return setColour( "[0;31m" ); case Colour::Green: return setColour( "[0;32m" ); case Colour::Blue: return setColour( "[0;34m" ); case Colour::Cyan: return setColour( "[0;36m" ); case Colour::Yellow: return setColour( "[0;33m" ); case Colour::Grey: return setColour( "[1;30m" ); case Colour::LightGrey: return setColour( "[0;37m" ); case Colour::BrightRed: return setColour( "[1;31m" ); case Colour::BrightGreen: return setColour( "[1;32m" ); case Colour::BrightWhite: return setColour( "[1;37m" ); case Colour::Bright: throw std::logic_error( "not a colour" ); } } static IColourImpl* instance() { static PosixColourImpl s_instance; return &s_instance; } private: void setColour( const char* _escapeCode ) { Catch::cout() << '\033' << _escapeCode; } }; IColourImpl* platformColourInstance() { ErrnoGuard guard; Ptr config = getCurrentContext().getConfig(); UseColour::YesOrNo colourMode = config ? config->useColour() : UseColour::Auto; if( colourMode == UseColour::Auto ) colourMode = (!isDebuggerActive() && isatty(STDOUT_FILENO) ) ? UseColour::Yes : UseColour::No; return colourMode == UseColour::Yes ? PosixColourImpl::instance() : NoColourImpl::instance(); } } // end anon namespace } // end namespace Catch #else // not Windows or ANSI /////////////////////////////////////////////// namespace Catch { static IColourImpl* platformColourInstance() { return NoColourImpl::instance(); } } // end namespace Catch #endif // Windows/ ANSI/ None namespace Catch { Colour::Colour( Code _colourCode ) : m_moved( false ) { use( _colourCode ); } Colour::Colour( Colour const& _other ) : m_moved( false ) { const_cast( _other ).m_moved = true; } Colour::~Colour(){ if( !m_moved ) use( None ); } void Colour::use( Code _colourCode ) { static IColourImpl* impl = platformColourInstance(); impl->use( _colourCode ); } } // end namespace Catch #endif // TWOBLUECUBES_CATCH_CONSOLE_COLOUR_IMPL_HPP_INCLUDED catch-1.12.1/include/internal/catch_context.h000066400000000000000000000026701325474075300211330ustar00rootroot00000000000000/* * Created by Phil on 31/12/2010. * Copyright 2010 Two Blue Cubes Ltd. All rights reserved. * * Distributed under the Boost Software License, Version 1.0. (See accompanying * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) */ #ifndef TWOBLUECUBES_CATCH_CONTEXT_H_INCLUDED #define TWOBLUECUBES_CATCH_CONTEXT_H_INCLUDED #include "catch_interfaces_generators.h" #include "catch_ptr.hpp" namespace Catch { class TestCase; class Stream; struct IResultCapture; struct IRunner; struct IGeneratorsForTest; struct IConfig; struct IContext { virtual ~IContext(); virtual IResultCapture* getResultCapture() = 0; virtual IRunner* getRunner() = 0; virtual size_t getGeneratorIndex( std::string const& fileInfo, size_t totalSize ) = 0; virtual bool advanceGeneratorsForCurrentTest() = 0; virtual Ptr getConfig() const = 0; }; struct IMutableContext : IContext { virtual ~IMutableContext(); virtual void setResultCapture( IResultCapture* resultCapture ) = 0; virtual void setRunner( IRunner* runner ) = 0; virtual void setConfig( Ptr const& config ) = 0; }; IContext& getCurrentContext(); IMutableContext& getCurrentMutableContext(); void cleanUpContext(); Stream createStream( std::string const& streamName ); } #endif // TWOBLUECUBES_CATCH_CONTEXT_H_INCLUDED catch-1.12.1/include/internal/catch_context_impl.hpp000066400000000000000000000067121325474075300225150ustar00rootroot00000000000000/* * Created by Phil on 31/12/2010. * Copyright 2010 Two Blue Cubes Ltd. All rights reserved. * * Distributed under the Boost Software License, Version 1.0. (See accompanying * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) */ #ifndef TWOBLUECUBES_CATCH_CONTEXT_IMPL_HPP_INCLUDED #define TWOBLUECUBES_CATCH_CONTEXT_IMPL_HPP_INCLUDED #include "catch_run_context.hpp" #include "catch_context.h" #include "catch_stream.hpp" #include "catch_common.h" namespace Catch { class Context : public IMutableContext { Context() : m_config( CATCH_NULL ), m_runner( CATCH_NULL ), m_resultCapture( CATCH_NULL ) {} Context( Context const& ); void operator=( Context const& ); public: virtual ~Context() { deleteAllValues( m_generatorsByTestName ); } public: // IContext virtual IResultCapture* getResultCapture() { return m_resultCapture; } virtual IRunner* getRunner() { return m_runner; } virtual size_t getGeneratorIndex( std::string const& fileInfo, size_t totalSize ) { return getGeneratorsForCurrentTest() .getGeneratorInfo( fileInfo, totalSize ) .getCurrentIndex(); } virtual bool advanceGeneratorsForCurrentTest() { IGeneratorsForTest* generators = findGeneratorsForCurrentTest(); return generators && generators->moveNext(); } virtual Ptr getConfig() const { return m_config; } public: // IMutableContext virtual void setResultCapture( IResultCapture* resultCapture ) { m_resultCapture = resultCapture; } virtual void setRunner( IRunner* runner ) { m_runner = runner; } virtual void setConfig( Ptr const& config ) { m_config = config; } friend IMutableContext& getCurrentMutableContext(); private: IGeneratorsForTest* findGeneratorsForCurrentTest() { std::string testName = getResultCapture()->getCurrentTestName(); std::map::const_iterator it = m_generatorsByTestName.find( testName ); return it != m_generatorsByTestName.end() ? it->second : CATCH_NULL; } IGeneratorsForTest& getGeneratorsForCurrentTest() { IGeneratorsForTest* generators = findGeneratorsForCurrentTest(); if( !generators ) { std::string testName = getResultCapture()->getCurrentTestName(); generators = createGeneratorsForTest(); m_generatorsByTestName.insert( std::make_pair( testName, generators ) ); } return *generators; } private: Ptr m_config; IRunner* m_runner; IResultCapture* m_resultCapture; std::map m_generatorsByTestName; }; namespace { Context* currentContext = CATCH_NULL; } IMutableContext& getCurrentMutableContext() { if( !currentContext ) currentContext = new Context(); return *currentContext; } IContext& getCurrentContext() { return getCurrentMutableContext(); } void cleanUpContext() { delete currentContext; currentContext = CATCH_NULL; } } #endif // TWOBLUECUBES_CATCH_CONTEXT_IMPL_HPP_INCLUDED catch-1.12.1/include/internal/catch_debugger.h000066400000000000000000000035571325474075300212400ustar00rootroot00000000000000/* * Created by Phil on 3/12/2013. * Copyright 2013 Two Blue Cubes Ltd. All rights reserved. * * Distributed under the Boost Software License, Version 1.0. (See accompanying * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) * */ #ifndef TWOBLUECUBES_CATCH_DEBUGGER_H_INCLUDED #define TWOBLUECUBES_CATCH_DEBUGGER_H_INCLUDED #include "catch_platform.h" #include namespace Catch{ bool isDebuggerActive(); void writeToDebugConsole( std::string const& text ); } #ifdef CATCH_PLATFORM_MAC // The following code snippet based on: // http://cocoawithlove.com/2008/03/break-into-debugger.html #if defined(__ppc64__) || defined(__ppc__) #define CATCH_TRAP() \ __asm__("li r0, 20\nsc\nnop\nli r0, 37\nli r4, 2\nsc\nnop\n" \ : : : "memory","r0","r3","r4" ) /* NOLINT */ #else #define CATCH_TRAP() __asm__("int $3\n" : : /* NOLINT */ ) #endif #elif defined(CATCH_PLATFORM_LINUX) // If we can use inline assembler, do it because this allows us to break // directly at the location of the failing check instead of breaking inside // raise() called from it, i.e. one stack frame below. #if defined(__GNUC__) && (defined(__i386) || defined(__x86_64)) #define CATCH_TRAP() asm volatile ("int $3") /* NOLINT */ #else // Fall back to the generic way. #include #define CATCH_TRAP() raise(SIGTRAP) #endif #elif defined(_MSC_VER) #define CATCH_TRAP() __debugbreak() #elif defined(__MINGW32__) extern "C" __declspec(dllimport) void __stdcall DebugBreak(); #define CATCH_TRAP() DebugBreak() #endif #ifdef CATCH_TRAP #define CATCH_BREAK_INTO_DEBUGGER() if( Catch::isDebuggerActive() ) { CATCH_TRAP(); } #else #define CATCH_BREAK_INTO_DEBUGGER() Catch::alwaysTrue(); #endif #endif // TWOBLUECUBES_CATCH_DEBUGGER_H_INCLUDED catch-1.12.1/include/internal/catch_debugger.hpp000066400000000000000000000105441325474075300215720ustar00rootroot00000000000000/* * Created by Phil on 27/12/2010. * Copyright 2010 Two Blue Cubes Ltd. All rights reserved. * * Distributed under the Boost Software License, Version 1.0. (See accompanying * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) * */ #ifndef TWOBLUECUBES_CATCH_DEBUGGER_HPP_INCLUDED #define TWOBLUECUBES_CATCH_DEBUGGER_HPP_INCLUDED #include "catch_debugger.h" #include "catch_errno_guard.hpp" #ifdef CATCH_PLATFORM_MAC #include #include #include #include #include namespace Catch{ // The following function is taken directly from the following technical note: // http://developer.apple.com/library/mac/#qa/qa2004/qa1361.html // Returns true if the current process is being debugged (either // running under the debugger or has a debugger attached post facto). bool isDebuggerActive(){ int mib[4]; struct kinfo_proc info; size_t size; // Initialize the flags so that, if sysctl fails for some bizarre // reason, we get a predictable result. info.kp_proc.p_flag = 0; // Initialize mib, which tells sysctl the info we want, in this case // we're looking for information about a specific process ID. mib[0] = CTL_KERN; mib[1] = KERN_PROC; mib[2] = KERN_PROC_PID; mib[3] = getpid(); // Call sysctl. size = sizeof(info); if( sysctl(mib, sizeof(mib) / sizeof(*mib), &info, &size, CATCH_NULL, 0) != 0 ) { Catch::cerr() << "\n** Call to sysctl failed - unable to determine if debugger is active **\n" << std::endl; return false; } // We're being debugged if the P_TRACED flag is set. return ( (info.kp_proc.p_flag & P_TRACED) != 0 ); } } // namespace Catch #elif defined(CATCH_PLATFORM_LINUX) #include #include namespace Catch{ // The standard POSIX way of detecting a debugger is to attempt to // ptrace() the process, but this needs to be done from a child and not // this process itself to still allow attaching to this process later // if wanted, so is rather heavy. Under Linux we have the PID of the // "debugger" (which doesn't need to be gdb, of course, it could also // be strace, for example) in /proc/$PID/status, so just get it from // there instead. bool isDebuggerActive(){ // Libstdc++ has a bug, where std::ifstream sets errno to 0 // This way our users can properly assert over errno values ErrnoGuard guard; std::ifstream in("/proc/self/status"); for( std::string line; std::getline(in, line); ) { static const int PREFIX_LEN = 11; if( line.compare(0, PREFIX_LEN, "TracerPid:\t") == 0 ) { // We're traced if the PID is not 0 and no other PID starts // with 0 digit, so it's enough to check for just a single // character. return line.length() > PREFIX_LEN && line[PREFIX_LEN] != '0'; } } return false; } } // namespace Catch #elif defined(_MSC_VER) extern "C" __declspec(dllimport) int __stdcall IsDebuggerPresent(); namespace Catch { bool isDebuggerActive() { return IsDebuggerPresent() != 0; } } #elif defined(__MINGW32__) extern "C" __declspec(dllimport) int __stdcall IsDebuggerPresent(); namespace Catch { bool isDebuggerActive() { return IsDebuggerPresent() != 0; } } #else namespace Catch { inline bool isDebuggerActive() { return false; } } #endif // Platform #ifdef CATCH_PLATFORM_WINDOWS #include "catch_windows_h_proxy.h" namespace Catch { void writeToDebugConsole( std::string const& text ) { ::OutputDebugStringA( text.c_str() ); } } #else namespace Catch { void writeToDebugConsole( std::string const& text ) { // !TBD: Need a version for Mac/ XCode and other IDEs Catch::cout() << text; } } #endif // Platform #endif // TWOBLUECUBES_CATCH_DEBUGGER_HPP_INCLUDED catch-1.12.1/include/internal/catch_default_main.hpp000066400000000000000000000023031325474075300224300ustar00rootroot00000000000000/* * Created by Phil on 20/05/2011. * Copyright 2011 Two Blue Cubes Ltd. All rights reserved. * * Distributed under the Boost Software License, Version 1.0. (See accompanying * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) */ #ifndef TWOBLUECUBES_CATCH_DEFAULT_MAIN_HPP_INCLUDED #define TWOBLUECUBES_CATCH_DEFAULT_MAIN_HPP_INCLUDED #ifndef __OBJC__ #if defined(WIN32) && defined(_UNICODE) && !defined(DO_NOT_USE_WMAIN) // Standard C/C++ Win32 Unicode wmain entry point extern "C" int wmain (int argc, wchar_t * argv[], wchar_t * []) { #else // Standard C/C++ main entry point int main (int argc, char * argv[]) { #endif int result = Catch::Session().run( argc, argv ); return ( result < 0xff ? result : 0xff ); } #else // __OBJC__ // Objective-C entry point int main (int argc, char * const argv[]) { #if !CATCH_ARC_ENABLED NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; #endif Catch::registerTestMethods(); int result = Catch::Session().run( argc, (char* const*)argv ); #if !CATCH_ARC_ENABLED [pool drain]; #endif return ( result < 0xff ? result : 0xff ); } #endif // __OBJC__ #endif // TWOBLUECUBES_CATCH_DEFAULT_MAIN_HPP_INCLUDED catch-1.12.1/include/internal/catch_errno_guard.hpp000066400000000000000000000010721325474075300223110ustar00rootroot00000000000000/* * Created by Martin on 06/03/2017. * * Distributed under the Boost Software License, Version 1.0. (See accompanying * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) */ #ifndef TWOBLUECUBES_CATCH_ERRNO_GUARD_HPP_INCLUDED #define TWOBLUECUBES_CATCH_ERRNO_GUARD_HPP_INCLUDED #include namespace Catch { class ErrnoGuard { public: ErrnoGuard():m_oldErrno(errno){} ~ErrnoGuard() { errno = m_oldErrno; } private: int m_oldErrno; }; } #endif // TWOBLUECUBES_CATCH_ERRNO_GUARD_HPP_INCLUDED catch-1.12.1/include/internal/catch_evaluate.hpp000066400000000000000000000216231325474075300216140ustar00rootroot00000000000000/* * Created by Phil on 04/03/2011. * Copyright 2011 Two Blue Cubes Ltd. All rights reserved. * * Distributed under the Boost Software License, Version 1.0. (See accompanying * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) */ #ifndef TWOBLUECUBES_CATCH_EVALUATE_HPP_INCLUDED #define TWOBLUECUBES_CATCH_EVALUATE_HPP_INCLUDED #ifdef _MSC_VER #pragma warning(push) #pragma warning(disable:4389) // '==' : signed/unsigned mismatch #pragma warning(disable:4018) // more "signed/unsigned mismatch" #pragma warning(disable:4312) // Converting int to T* using reinterpret_cast (issue on x64 platform) #endif #include namespace Catch { namespace Internal { enum Operator { IsEqualTo, IsNotEqualTo, IsLessThan, IsGreaterThan, IsLessThanOrEqualTo, IsGreaterThanOrEqualTo }; template struct OperatorTraits { static const char* getName(){ return "*error*"; } }; template<> struct OperatorTraits { static const char* getName(){ return "=="; } }; template<> struct OperatorTraits { static const char* getName(){ return "!="; } }; template<> struct OperatorTraits { static const char* getName(){ return "<"; } }; template<> struct OperatorTraits { static const char* getName(){ return ">"; } }; template<> struct OperatorTraits { static const char* getName(){ return "<="; } }; template<> struct OperatorTraits{ static const char* getName(){ return ">="; } }; template T& opCast(T const& t) { return const_cast(t); } // nullptr_t support based on pull request #154 from Konstantin Baumann #ifdef CATCH_CONFIG_CPP11_NULLPTR inline std::nullptr_t opCast(std::nullptr_t) { return nullptr; } #endif // CATCH_CONFIG_CPP11_NULLPTR // So the compare overloads can be operator agnostic we convey the operator as a template // enum, which is used to specialise an Evaluator for doing the comparison. template struct Evaluator{}; template struct Evaluator { static bool evaluate( T1 const& lhs, T2 const& rhs) { return bool( opCast( lhs ) == opCast( rhs ) ); } }; template struct Evaluator { static bool evaluate( T1 const& lhs, T2 const& rhs ) { return bool( opCast( lhs ) != opCast( rhs ) ); } }; template struct Evaluator { static bool evaluate( T1 const& lhs, T2 const& rhs ) { return bool( opCast( lhs ) < opCast( rhs ) ); } }; template struct Evaluator { static bool evaluate( T1 const& lhs, T2 const& rhs ) { return bool( opCast( lhs ) > opCast( rhs ) ); } }; template struct Evaluator { static bool evaluate( T1 const& lhs, T2 const& rhs ) { return bool( opCast( lhs ) >= opCast( rhs ) ); } }; template struct Evaluator { static bool evaluate( T1 const& lhs, T2 const& rhs ) { return bool( opCast( lhs ) <= opCast( rhs ) ); } }; template bool applyEvaluator( T1 const& lhs, T2 const& rhs ) { return Evaluator::evaluate( lhs, rhs ); } // This level of indirection allows us to specialise for integer types // to avoid signed/ unsigned warnings // "base" overload template bool compare( T1 const& lhs, T2 const& rhs ) { return Evaluator::evaluate( lhs, rhs ); } // unsigned X to int template bool compare( unsigned int lhs, int rhs ) { return applyEvaluator( lhs, static_cast( rhs ) ); } template bool compare( unsigned long lhs, int rhs ) { return applyEvaluator( lhs, static_cast( rhs ) ); } template bool compare( unsigned char lhs, int rhs ) { return applyEvaluator( lhs, static_cast( rhs ) ); } // unsigned X to long template bool compare( unsigned int lhs, long rhs ) { return applyEvaluator( lhs, static_cast( rhs ) ); } template bool compare( unsigned long lhs, long rhs ) { return applyEvaluator( lhs, static_cast( rhs ) ); } template bool compare( unsigned char lhs, long rhs ) { return applyEvaluator( lhs, static_cast( rhs ) ); } // int to unsigned X template bool compare( int lhs, unsigned int rhs ) { return applyEvaluator( static_cast( lhs ), rhs ); } template bool compare( int lhs, unsigned long rhs ) { return applyEvaluator( static_cast( lhs ), rhs ); } template bool compare( int lhs, unsigned char rhs ) { return applyEvaluator( static_cast( lhs ), rhs ); } // long to unsigned X template bool compare( long lhs, unsigned int rhs ) { return applyEvaluator( static_cast( lhs ), rhs ); } template bool compare( long lhs, unsigned long rhs ) { return applyEvaluator( static_cast( lhs ), rhs ); } template bool compare( long lhs, unsigned char rhs ) { return applyEvaluator( static_cast( lhs ), rhs ); } // pointer to long (when comparing against NULL) template bool compare( long lhs, T* rhs ) { return Evaluator::evaluate( reinterpret_cast( lhs ), rhs ); } template bool compare( T* lhs, long rhs ) { return Evaluator::evaluate( lhs, reinterpret_cast( rhs ) ); } // pointer to int (when comparing against NULL) template bool compare( int lhs, T* rhs ) { return Evaluator::evaluate( reinterpret_cast( lhs ), rhs ); } template bool compare( T* lhs, int rhs ) { return Evaluator::evaluate( lhs, reinterpret_cast( rhs ) ); } #ifdef CATCH_CONFIG_CPP11_LONG_LONG // long long to unsigned X template bool compare( long long lhs, unsigned int rhs ) { return applyEvaluator( static_cast( lhs ), rhs ); } template bool compare( long long lhs, unsigned long rhs ) { return applyEvaluator( static_cast( lhs ), rhs ); } template bool compare( long long lhs, unsigned long long rhs ) { return applyEvaluator( static_cast( lhs ), rhs ); } template bool compare( long long lhs, unsigned char rhs ) { return applyEvaluator( static_cast( lhs ), rhs ); } // unsigned long long to X template bool compare( unsigned long long lhs, int rhs ) { return applyEvaluator( static_cast( lhs ), rhs ); } template bool compare( unsigned long long lhs, long rhs ) { return applyEvaluator( static_cast( lhs ), rhs ); } template bool compare( unsigned long long lhs, long long rhs ) { return applyEvaluator( static_cast( lhs ), rhs ); } template bool compare( unsigned long long lhs, char rhs ) { return applyEvaluator( static_cast( lhs ), rhs ); } // pointer to long long (when comparing against NULL) template bool compare( long long lhs, T* rhs ) { return Evaluator::evaluate( reinterpret_cast( lhs ), rhs ); } template bool compare( T* lhs, long long rhs ) { return Evaluator::evaluate( lhs, reinterpret_cast( rhs ) ); } #endif // CATCH_CONFIG_CPP11_LONG_LONG #ifdef CATCH_CONFIG_CPP11_NULLPTR // pointer to nullptr_t (when comparing against nullptr) template bool compare( std::nullptr_t, T* rhs ) { return Evaluator::evaluate( nullptr, rhs ); } template bool compare( T* lhs, std::nullptr_t ) { return Evaluator::evaluate( lhs, nullptr ); } #endif // CATCH_CONFIG_CPP11_NULLPTR } // end of namespace Internal } // end of namespace Catch #ifdef _MSC_VER #pragma warning(pop) #endif #endif // TWOBLUECUBES_CATCH_EVALUATE_HPP_INCLUDED catch-1.12.1/include/internal/catch_exception_translator_registry.hpp000066400000000000000000000041541325474075300262050ustar00rootroot00000000000000/* * Created by Phil on 20/04/2011. * Copyright 2011 Two Blue Cubes Ltd. All rights reserved. * * Distributed under the Boost Software License, Version 1.0. (See accompanying * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) */ #ifndef TWOBLUECUBES_CATCH_EXCEPTION_TRANSLATOR_REGISTRY_HPP_INCLUDED #define TWOBLUECUBES_CATCH_EXCEPTION_TRANSLATOR_REGISTRY_HPP_INCLUDED #include "catch_interfaces_exception.h" #include "catch_tostring.h" #ifdef __OBJC__ #import "Foundation/Foundation.h" #endif namespace Catch { class ExceptionTranslatorRegistry : public IExceptionTranslatorRegistry { public: ~ExceptionTranslatorRegistry() { deleteAll( m_translators ); } virtual void registerTranslator( const IExceptionTranslator* translator ) { m_translators.push_back( translator ); } virtual std::string translateActiveException() const { try { #ifdef __OBJC__ // In Objective-C try objective-c exceptions first @try { return tryTranslators(); } @catch (NSException *exception) { return Catch::toString( [exception description] ); } #else return tryTranslators(); #endif } catch( TestFailureException& ) { throw; } catch( std::exception& ex ) { return ex.what(); } catch( std::string& msg ) { return msg; } catch( const char* msg ) { return msg; } catch(...) { return "Unknown exception"; } } std::string tryTranslators() const { if( m_translators.empty() ) throw; else return m_translators[0]->translate( m_translators.begin()+1, m_translators.end() ); } private: std::vector m_translators; }; } #endif // TWOBLUECUBES_CATCH_EXCEPTION_TRANSLATOR_REGISTRY_HPP_INCLUDED catch-1.12.1/include/internal/catch_expression_lhs.hpp000066400000000000000000000126511325474075300230540ustar00rootroot00000000000000/* * Created by Phil on 11/5/2012. * Copyright 2012 Two Blue Cubes Ltd. All rights reserved. * * Distributed under the Boost Software License, Version 1.0. (See accompanying * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) */ #ifndef TWOBLUECUBES_CATCH_EXPRESSION_LHS_HPP_INCLUDED #define TWOBLUECUBES_CATCH_EXPRESSION_LHS_HPP_INCLUDED #include "catch_result_builder.h" #include "catch_evaluate.hpp" #include "catch_tostring.h" namespace Catch { template class BinaryExpression; template class MatchExpression; // Wraps the LHS of an expression and overloads comparison operators // for also capturing those and RHS (if any) template class ExpressionLhs : public DecomposedExpression { public: ExpressionLhs( ResultBuilder& rb, T lhs ) : m_rb( rb ), m_lhs( lhs ), m_truthy(false) {} ExpressionLhs& operator = ( const ExpressionLhs& ); template BinaryExpression operator == ( RhsT const& rhs ) { return captureExpression( rhs ); } template BinaryExpression operator != ( RhsT const& rhs ) { return captureExpression( rhs ); } template BinaryExpression operator < ( RhsT const& rhs ) { return captureExpression( rhs ); } template BinaryExpression operator > ( RhsT const& rhs ) { return captureExpression( rhs ); } template BinaryExpression operator <= ( RhsT const& rhs ) { return captureExpression( rhs ); } template BinaryExpression operator >= ( RhsT const& rhs ) { return captureExpression( rhs ); } BinaryExpression operator == ( bool rhs ) { return captureExpression( rhs ); } BinaryExpression operator != ( bool rhs ) { return captureExpression( rhs ); } void endExpression() { m_truthy = m_lhs ? true : false; m_rb .setResultType( m_truthy ) .endExpression( *this ); } virtual void reconstructExpression( std::string& dest ) const CATCH_OVERRIDE { dest = Catch::toString( m_lhs ); } private: template BinaryExpression captureExpression( RhsT& rhs ) const { return BinaryExpression( m_rb, m_lhs, rhs ); } template BinaryExpression captureExpression( bool rhs ) const { return BinaryExpression( m_rb, m_lhs, rhs ); } private: ResultBuilder& m_rb; T m_lhs; bool m_truthy; }; template class BinaryExpression : public DecomposedExpression { public: BinaryExpression( ResultBuilder& rb, LhsT lhs, RhsT rhs ) : m_rb( rb ), m_lhs( lhs ), m_rhs( rhs ) {} BinaryExpression& operator = ( BinaryExpression& ); void endExpression() const { m_rb .setResultType( Internal::compare( m_lhs, m_rhs ) ) .endExpression( *this ); } virtual bool isBinaryExpression() const CATCH_OVERRIDE { return true; } virtual void reconstructExpression( std::string& dest ) const CATCH_OVERRIDE { std::string lhs = Catch::toString( m_lhs ); std::string rhs = Catch::toString( m_rhs ); char delim = lhs.size() + rhs.size() < 40 && lhs.find('\n') == std::string::npos && rhs.find('\n') == std::string::npos ? ' ' : '\n'; dest.reserve( 7 + lhs.size() + rhs.size() ); // 2 for spaces around operator // 2 for operator // 2 for parentheses (conditionally added later) // 1 for negation (conditionally added later) dest = lhs; dest += delim; dest += Internal::OperatorTraits::getName(); dest += delim; dest += rhs; } private: ResultBuilder& m_rb; LhsT m_lhs; RhsT m_rhs; }; template class MatchExpression : public DecomposedExpression { public: MatchExpression( ArgT arg, MatcherT matcher, char const* matcherString ) : m_arg( arg ), m_matcher( matcher ), m_matcherString( matcherString ) {} virtual bool isBinaryExpression() const CATCH_OVERRIDE { return true; } virtual void reconstructExpression( std::string& dest ) const CATCH_OVERRIDE { std::string matcherAsString = m_matcher.toString(); dest = Catch::toString( m_arg ); dest += ' '; if( matcherAsString == Detail::unprintableString ) dest += m_matcherString; else dest += matcherAsString; } private: ArgT m_arg; MatcherT m_matcher; char const* m_matcherString; }; } // end namespace Catch #endif // TWOBLUECUBES_CATCH_EXPRESSION_LHS_HPP_INCLUDED catch-1.12.1/include/internal/catch_fatal_condition.hpp000066400000000000000000000147551325474075300231530ustar00rootroot00000000000000/* * Created by Phil on 21/08/2014 * Copyright 2014 Two Blue Cubes Ltd. All rights reserved. * * Distributed under the Boost Software License, Version 1.0. (See accompanying * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) * */ #ifndef TWOBLUECUBES_CATCH_FATAL_CONDITION_H_INCLUDED #define TWOBLUECUBES_CATCH_FATAL_CONDITION_H_INCLUDED namespace Catch { // Report the error condition inline void reportFatal( std::string const& message ) { IContext& context = Catch::getCurrentContext(); IResultCapture* resultCapture = context.getResultCapture(); resultCapture->handleFatalErrorCondition( message ); } } // namespace Catch #if defined ( CATCH_PLATFORM_WINDOWS ) ///////////////////////////////////////// #include "catch_windows_h_proxy.h" # if !defined ( CATCH_CONFIG_WINDOWS_SEH ) namespace Catch { struct FatalConditionHandler { void reset() {} }; } # else // CATCH_CONFIG_WINDOWS_SEH is defined namespace Catch { struct SignalDefs { DWORD id; const char* name; }; extern SignalDefs signalDefs[]; // There is no 1-1 mapping between signals and windows exceptions. // Windows can easily distinguish between SO and SigSegV, // but SigInt, SigTerm, etc are handled differently. SignalDefs signalDefs[] = { { EXCEPTION_ILLEGAL_INSTRUCTION, "SIGILL - Illegal instruction signal" }, { EXCEPTION_STACK_OVERFLOW, "SIGSEGV - Stack overflow" }, { EXCEPTION_ACCESS_VIOLATION, "SIGSEGV - Segmentation violation signal" }, { EXCEPTION_INT_DIVIDE_BY_ZERO, "Divide by zero error" }, }; struct FatalConditionHandler { static LONG CALLBACK handleVectoredException(PEXCEPTION_POINTERS ExceptionInfo) { for (int i = 0; i < sizeof(signalDefs) / sizeof(SignalDefs); ++i) { if (ExceptionInfo->ExceptionRecord->ExceptionCode == signalDefs[i].id) { reportFatal(signalDefs[i].name); } } // If its not an exception we care about, pass it along. // This stops us from eating debugger breaks etc. return EXCEPTION_CONTINUE_SEARCH; } FatalConditionHandler() { isSet = true; // 32k seems enough for Catch to handle stack overflow, // but the value was found experimentally, so there is no strong guarantee guaranteeSize = 32 * 1024; exceptionHandlerHandle = CATCH_NULL; // Register as first handler in current chain exceptionHandlerHandle = AddVectoredExceptionHandler(1, handleVectoredException); // Pass in guarantee size to be filled SetThreadStackGuarantee(&guaranteeSize); } static void reset() { if (isSet) { // Unregister handler and restore the old guarantee RemoveVectoredExceptionHandler(exceptionHandlerHandle); SetThreadStackGuarantee(&guaranteeSize); exceptionHandlerHandle = CATCH_NULL; isSet = false; } } ~FatalConditionHandler() { reset(); } private: static bool isSet; static ULONG guaranteeSize; static PVOID exceptionHandlerHandle; }; bool FatalConditionHandler::isSet = false; ULONG FatalConditionHandler::guaranteeSize = 0; PVOID FatalConditionHandler::exceptionHandlerHandle = CATCH_NULL; } // namespace Catch # endif // CATCH_CONFIG_WINDOWS_SEH #else // Not Windows - assumed to be POSIX compatible ////////////////////////// # if !defined(CATCH_CONFIG_POSIX_SIGNALS) namespace Catch { struct FatalConditionHandler { void reset() {} }; } # else // CATCH_CONFIG_POSIX_SIGNALS is defined #include namespace Catch { struct SignalDefs { int id; const char* name; }; extern SignalDefs signalDefs[]; SignalDefs signalDefs[] = { { SIGINT, "SIGINT - Terminal interrupt signal" }, { SIGILL, "SIGILL - Illegal instruction signal" }, { SIGFPE, "SIGFPE - Floating point error signal" }, { SIGSEGV, "SIGSEGV - Segmentation violation signal" }, { SIGTERM, "SIGTERM - Termination request signal" }, { SIGABRT, "SIGABRT - Abort (abnormal termination) signal" } }; struct FatalConditionHandler { static bool isSet; static struct sigaction oldSigActions [sizeof(signalDefs)/sizeof(SignalDefs)]; static stack_t oldSigStack; static char altStackMem[SIGSTKSZ]; static void handleSignal( int sig ) { std::string name = ""; for (std::size_t i = 0; i < sizeof(signalDefs) / sizeof(SignalDefs); ++i) { SignalDefs &def = signalDefs[i]; if (sig == def.id) { name = def.name; break; } } reset(); reportFatal(name); raise( sig ); } FatalConditionHandler() { isSet = true; stack_t sigStack; sigStack.ss_sp = altStackMem; sigStack.ss_size = SIGSTKSZ; sigStack.ss_flags = 0; sigaltstack(&sigStack, &oldSigStack); struct sigaction sa = { 0 }; sa.sa_handler = handleSignal; sa.sa_flags = SA_ONSTACK; for (std::size_t i = 0; i < sizeof(signalDefs)/sizeof(SignalDefs); ++i) { sigaction(signalDefs[i].id, &sa, &oldSigActions[i]); } } ~FatalConditionHandler() { reset(); } static void reset() { if( isSet ) { // Set signals back to previous values -- hopefully nobody overwrote them in the meantime for( std::size_t i = 0; i < sizeof(signalDefs)/sizeof(SignalDefs); ++i ) { sigaction(signalDefs[i].id, &oldSigActions[i], CATCH_NULL); } // Return the old stack sigaltstack(&oldSigStack, CATCH_NULL); isSet = false; } } }; bool FatalConditionHandler::isSet = false; struct sigaction FatalConditionHandler::oldSigActions[sizeof(signalDefs)/sizeof(SignalDefs)] = {}; stack_t FatalConditionHandler::oldSigStack = {}; char FatalConditionHandler::altStackMem[SIGSTKSZ] = {}; } // namespace Catch # endif // CATCH_CONFIG_POSIX_SIGNALS #endif // not Windows #endif // TWOBLUECUBES_CATCH_FATAL_CONDITION_H_INCLUDED catch-1.12.1/include/internal/catch_generators.hpp000066400000000000000000000122271325474075300221570ustar00rootroot00000000000000/* * Created by Phil on 27/01/2011. * Copyright 2011 Two Blue Cubes Ltd. All rights reserved. * * Distributed under the Boost Software License, Version 1.0. (See accompanying * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) */ #ifndef TWOBLUECUBES_CATCH_GENERATORS_HPP_INCLUDED #define TWOBLUECUBES_CATCH_GENERATORS_HPP_INCLUDED #include "catch_context.h" #include #include #include namespace Catch { template struct IGenerator { virtual ~IGenerator() {} virtual T getValue( std::size_t index ) const = 0; virtual std::size_t size () const = 0; }; template class BetweenGenerator : public IGenerator { public: BetweenGenerator( T from, T to ) : m_from( from ), m_to( to ){} virtual T getValue( std::size_t index ) const { return m_from+static_cast( index ); } virtual std::size_t size() const { return static_cast( 1+m_to-m_from ); } private: T m_from; T m_to; }; template class ValuesGenerator : public IGenerator { public: ValuesGenerator(){} void add( T value ) { m_values.push_back( value ); } virtual T getValue( std::size_t index ) const { return m_values[index]; } virtual std::size_t size() const { return m_values.size(); } private: std::vector m_values; }; template class CompositeGenerator { public: CompositeGenerator() : m_totalSize( 0 ) {} // *** Move semantics, similar to auto_ptr *** CompositeGenerator( CompositeGenerator& other ) : m_fileInfo( other.m_fileInfo ), m_totalSize( 0 ) { move( other ); } CompositeGenerator& setFileInfo( const char* fileInfo ) { m_fileInfo = fileInfo; return *this; } ~CompositeGenerator() { deleteAll( m_composed ); } operator T () const { size_t overallIndex = getCurrentContext().getGeneratorIndex( m_fileInfo, m_totalSize ); typename std::vector*>::const_iterator it = m_composed.begin(); typename std::vector*>::const_iterator itEnd = m_composed.end(); for( size_t index = 0; it != itEnd; ++it ) { const IGenerator* generator = *it; if( overallIndex >= index && overallIndex < index + generator->size() ) { return generator->getValue( overallIndex-index ); } index += generator->size(); } CATCH_INTERNAL_ERROR( "Indexed past end of generated range" ); return T(); // Suppress spurious "not all control paths return a value" warning in Visual Studio - if you know how to fix this please do so } void add( const IGenerator* generator ) { m_totalSize += generator->size(); m_composed.push_back( generator ); } CompositeGenerator& then( CompositeGenerator& other ) { move( other ); return *this; } CompositeGenerator& then( T value ) { ValuesGenerator* valuesGen = new ValuesGenerator(); valuesGen->add( value ); add( valuesGen ); return *this; } private: void move( CompositeGenerator& other ) { m_composed.insert( m_composed.end(), other.m_composed.begin(), other.m_composed.end() ); m_totalSize += other.m_totalSize; other.m_composed.clear(); } std::vector*> m_composed; std::string m_fileInfo; size_t m_totalSize; }; namespace Generators { template CompositeGenerator between( T from, T to ) { CompositeGenerator generators; generators.add( new BetweenGenerator( from, to ) ); return generators; } template CompositeGenerator values( T val1, T val2 ) { CompositeGenerator generators; ValuesGenerator* valuesGen = new ValuesGenerator(); valuesGen->add( val1 ); valuesGen->add( val2 ); generators.add( valuesGen ); return generators; } template CompositeGenerator values( T val1, T val2, T val3 ){ CompositeGenerator generators; ValuesGenerator* valuesGen = new ValuesGenerator(); valuesGen->add( val1 ); valuesGen->add( val2 ); valuesGen->add( val3 ); generators.add( valuesGen ); return generators; } template CompositeGenerator values( T val1, T val2, T val3, T val4 ) { CompositeGenerator generators; ValuesGenerator* valuesGen = new ValuesGenerator(); valuesGen->add( val1 ); valuesGen->add( val2 ); valuesGen->add( val3 ); valuesGen->add( val4 ); generators.add( valuesGen ); return generators; } } // end namespace Generators using namespace Generators; } // end namespace Catch #define INTERNAL_CATCH_LINESTR2( line ) #line #define INTERNAL_CATCH_LINESTR( line ) INTERNAL_CATCH_LINESTR2( line ) #define INTERNAL_CATCH_GENERATE( expr ) expr.setFileInfo( __FILE__ "(" INTERNAL_CATCH_LINESTR( __LINE__ ) ")" ) #endif // TWOBLUECUBES_CATCH_GENERATORS_HPP_INCLUDED catch-1.12.1/include/internal/catch_generators_impl.hpp000066400000000000000000000047161325474075300232040ustar00rootroot00000000000000/* * Created by Phil on 28/01/2011. * Copyright 2011 Two Blue Cubes Ltd. All rights reserved. * * Distributed under the Boost Software License, Version 1.0. (See accompanying * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) */ #ifndef TWOBLUECUBES_CATCH_GENERATORS_IMPL_HPP_INCLUDED #define TWOBLUECUBES_CATCH_GENERATORS_IMPL_HPP_INCLUDED #include "catch_interfaces_generators.h" #include "catch_common.h" #include #include #include namespace Catch { struct GeneratorInfo : IGeneratorInfo { GeneratorInfo( std::size_t size ) : m_size( size ), m_currentIndex( 0 ) {} bool moveNext() { if( ++m_currentIndex == m_size ) { m_currentIndex = 0; return false; } return true; } std::size_t getCurrentIndex() const { return m_currentIndex; } std::size_t m_size; std::size_t m_currentIndex; }; /////////////////////////////////////////////////////////////////////////// class GeneratorsForTest : public IGeneratorsForTest { public: ~GeneratorsForTest() { deleteAll( m_generatorsInOrder ); } IGeneratorInfo& getGeneratorInfo( std::string const& fileInfo, std::size_t size ) { std::map::const_iterator it = m_generatorsByName.find( fileInfo ); if( it == m_generatorsByName.end() ) { IGeneratorInfo* info = new GeneratorInfo( size ); m_generatorsByName.insert( std::make_pair( fileInfo, info ) ); m_generatorsInOrder.push_back( info ); return *info; } return *it->second; } bool moveNext() { std::vector::const_iterator it = m_generatorsInOrder.begin(); std::vector::const_iterator itEnd = m_generatorsInOrder.end(); for(; it != itEnd; ++it ) { if( (*it)->moveNext() ) return true; } return false; } private: std::map m_generatorsByName; std::vector m_generatorsInOrder; }; IGeneratorsForTest* createGeneratorsForTest() { return new GeneratorsForTest(); } } // end namespace Catch #endif // TWOBLUECUBES_CATCH_GENERATORS_IMPL_HPP_INCLUDED catch-1.12.1/include/internal/catch_impl.hpp000066400000000000000000000075271325474075300207560ustar00rootroot00000000000000/* * Created by Phil on 5/8/2012. * Copyright 2012 Two Blue Cubes Ltd. All rights reserved. * * Distributed under the Boost Software License, Version 1.0. (See accompanying * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) */ #ifndef TWOBLUECUBES_CATCH_IMPL_HPP_INCLUDED #define TWOBLUECUBES_CATCH_IMPL_HPP_INCLUDED // Collect all the implementation files together here // These are the equivalent of what would usually be cpp files #ifdef __clang__ #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wweak-vtables" #endif #include "../catch_session.hpp" #include "catch_registry_hub.hpp" #include "catch_notimplemented_exception.hpp" #include "catch_context_impl.hpp" #include "catch_console_colour_impl.hpp" #include "catch_generators_impl.hpp" #include "catch_assertionresult.hpp" #include "catch_test_case_info.hpp" #include "catch_test_spec.hpp" #include "catch_version.hpp" #include "catch_message.hpp" #include "catch_legacy_reporter_adapter.hpp" #include "catch_timer.hpp" #include "catch_common.hpp" #include "catch_section.hpp" #include "catch_debugger.hpp" #include "catch_tostring.hpp" #include "catch_result_builder.hpp" #include "catch_tag_alias_registry.hpp" #include "catch_test_case_tracker.hpp" #include "catch_matchers_string.hpp" #include "../reporters/catch_reporter_multi.hpp" #include "../reporters/catch_reporter_xml.hpp" #include "../reporters/catch_reporter_junit.hpp" #include "../reporters/catch_reporter_console.hpp" #include "../reporters/catch_reporter_compact.hpp" namespace Catch { // These are all here to avoid warnings about not having any out of line // virtual methods NonCopyable::~NonCopyable() {} IShared::~IShared() {} IStream::~IStream() CATCH_NOEXCEPT {} FileStream::~FileStream() CATCH_NOEXCEPT {} CoutStream::~CoutStream() CATCH_NOEXCEPT {} DebugOutStream::~DebugOutStream() CATCH_NOEXCEPT {} StreamBufBase::~StreamBufBase() CATCH_NOEXCEPT {} IContext::~IContext() {} IResultCapture::~IResultCapture() {} ITestCase::~ITestCase() {} ITestCaseRegistry::~ITestCaseRegistry() {} IRegistryHub::~IRegistryHub() {} IMutableRegistryHub::~IMutableRegistryHub() {} IExceptionTranslator::~IExceptionTranslator() {} IExceptionTranslatorRegistry::~IExceptionTranslatorRegistry() {} IReporter::~IReporter() {} IReporterFactory::~IReporterFactory() {} IReporterRegistry::~IReporterRegistry() {} IStreamingReporter::~IStreamingReporter() {} AssertionStats::~AssertionStats() {} SectionStats::~SectionStats() {} TestCaseStats::~TestCaseStats() {} TestGroupStats::~TestGroupStats() {} TestRunStats::~TestRunStats() {} CumulativeReporterBase::SectionNode::~SectionNode() {} CumulativeReporterBase::~CumulativeReporterBase() {} StreamingReporterBase::~StreamingReporterBase() {} ConsoleReporter::~ConsoleReporter() {} CompactReporter::~CompactReporter() {} IRunner::~IRunner() {} IMutableContext::~IMutableContext() {} IConfig::~IConfig() {} XmlReporter::~XmlReporter() {} JunitReporter::~JunitReporter() {} TestRegistry::~TestRegistry() {} FreeFunctionTestCase::~FreeFunctionTestCase() {} IGeneratorInfo::~IGeneratorInfo() {} IGeneratorsForTest::~IGeneratorsForTest() {} WildcardPattern::~WildcardPattern() {} TestSpec::Pattern::~Pattern() {} TestSpec::NamePattern::~NamePattern() {} TestSpec::TagPattern::~TagPattern() {} TestSpec::ExcludedPattern::~ExcludedPattern() {} Matchers::Impl::MatcherUntypedBase::~MatcherUntypedBase() {} void Config::dummy() {} namespace TestCaseTracking { ITracker::~ITracker() {} TrackerBase::~TrackerBase() {} SectionTracker::~SectionTracker() {} IndexTracker::~IndexTracker() {} } } #ifdef __clang__ #pragma clang diagnostic pop #endif #endif // TWOBLUECUBES_CATCH_IMPL_HPP_INCLUDED catch-1.12.1/include/internal/catch_interfaces_capture.h000066400000000000000000000033251325474075300233130ustar00rootroot00000000000000/* * Created by Phil on 07/01/2011. * Copyright 2011 Two Blue Cubes Ltd. All rights reserved. * * Distributed under the Boost Software License, Version 1.0. (See accompanying * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) */ #ifndef TWOBLUECUBES_CATCH_INTERFACES_CAPTURE_H_INCLUDED #define TWOBLUECUBES_CATCH_INTERFACES_CAPTURE_H_INCLUDED #include #include "catch_result_type.h" #include "catch_common.h" namespace Catch { class TestCase; class AssertionResult; struct AssertionInfo; struct SectionInfo; struct SectionEndInfo; struct MessageInfo; class ScopedMessageBuilder; struct Counts; struct IResultCapture { virtual ~IResultCapture(); virtual void assertionEnded( AssertionResult const& result ) = 0; virtual bool sectionStarted( SectionInfo const& sectionInfo, Counts& assertions ) = 0; virtual void sectionEnded( SectionEndInfo const& endInfo ) = 0; virtual void sectionEndedEarly( SectionEndInfo const& endInfo ) = 0; virtual void pushScopedMessage( MessageInfo const& message ) = 0; virtual void popScopedMessage( MessageInfo const& message ) = 0; virtual std::string getCurrentTestName() const = 0; virtual const AssertionResult* getLastResult() const = 0; virtual void exceptionEarlyReported() = 0; virtual void handleFatalErrorCondition( std::string const& message ) = 0; virtual bool lastAssertionPassed() = 0; virtual void assertionPassed() = 0; virtual void assertionRun() = 0; }; IResultCapture& getResultCapture(); } #endif // TWOBLUECUBES_CATCH_INTERFACES_CAPTURE_H_INCLUDED catch-1.12.1/include/internal/catch_interfaces_config.h000066400000000000000000000040501325474075300231110ustar00rootroot00000000000000/* * Created by Phil on 05/06/2012. * Copyright 2012 Two Blue Cubes Ltd. All rights reserved. * * Distributed under the Boost Software License, Version 1.0. (See accompanying * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) */ #ifndef TWOBLUECUBES_CATCH_INTERFACES_CONFIG_H_INCLUDED #define TWOBLUECUBES_CATCH_INTERFACES_CONFIG_H_INCLUDED #include #include #include #include "catch_ptr.hpp" namespace Catch { struct Verbosity { enum Level { NoOutput = 0, Quiet, Normal }; }; struct WarnAbout { enum What { Nothing = 0x00, NoAssertions = 0x01 }; }; struct ShowDurations { enum OrNot { DefaultForReporter, Always, Never }; }; struct RunTests { enum InWhatOrder { InDeclarationOrder, InLexicographicalOrder, InRandomOrder }; }; struct UseColour { enum YesOrNo { Auto, Yes, No }; }; struct WaitForKeypress { enum When { Never, BeforeStart = 1, BeforeExit = 2, BeforeStartAndExit = BeforeStart | BeforeExit }; }; class TestSpec; struct IConfig : IShared { virtual ~IConfig(); virtual bool allowThrows() const = 0; virtual std::ostream& stream() const = 0; virtual std::string name() const = 0; virtual bool includeSuccessfulResults() const = 0; virtual bool shouldDebugBreak() const = 0; virtual bool warnAboutMissingAssertions() const = 0; virtual int abortAfter() const = 0; virtual bool showInvisibles() const = 0; virtual ShowDurations::OrNot showDurations() const = 0; virtual TestSpec const& testSpec() const = 0; virtual RunTests::InWhatOrder runOrder() const = 0; virtual unsigned int rngSeed() const = 0; virtual UseColour::YesOrNo useColour() const = 0; virtual std::vector const& getSectionsToRun() const = 0; }; } #endif // TWOBLUECUBES_CATCH_INTERFACES_CONFIG_H_INCLUDED catch-1.12.1/include/internal/catch_interfaces_exception.h000066400000000000000000000053321325474075300236460ustar00rootroot00000000000000/* * Created by Phil on 20/04/2011. * Copyright 2011 Two Blue Cubes Ltd. All rights reserved. * * Distributed under the Boost Software License, Version 1.0. (See accompanying * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) */ #ifndef TWOBLUECUBES_CATCH_INTERFACES_EXCEPTION_H_INCLUDED #define TWOBLUECUBES_CATCH_INTERFACES_EXCEPTION_H_INCLUDED #include #include #include "catch_interfaces_registry_hub.h" namespace Catch { typedef std::string(*exceptionTranslateFunction)(); struct IExceptionTranslator; typedef std::vector ExceptionTranslators; struct IExceptionTranslator { virtual ~IExceptionTranslator(); virtual std::string translate( ExceptionTranslators::const_iterator it, ExceptionTranslators::const_iterator itEnd ) const = 0; }; struct IExceptionTranslatorRegistry { virtual ~IExceptionTranslatorRegistry(); virtual std::string translateActiveException() const = 0; }; class ExceptionTranslatorRegistrar { template class ExceptionTranslator : public IExceptionTranslator { public: ExceptionTranslator( std::string(*translateFunction)( T& ) ) : m_translateFunction( translateFunction ) {} virtual std::string translate( ExceptionTranslators::const_iterator it, ExceptionTranslators::const_iterator itEnd ) const CATCH_OVERRIDE { try { if( it == itEnd ) throw; else return (*it)->translate( it+1, itEnd ); } catch( T& ex ) { return m_translateFunction( ex ); } } protected: std::string(*m_translateFunction)( T& ); }; public: template ExceptionTranslatorRegistrar( std::string(*translateFunction)( T& ) ) { getMutableRegistryHub().registerTranslator ( new ExceptionTranslator( translateFunction ) ); } }; } /////////////////////////////////////////////////////////////////////////////// #define INTERNAL_CATCH_TRANSLATE_EXCEPTION2( translatorName, signature ) \ static std::string translatorName( signature ); \ namespace{ Catch::ExceptionTranslatorRegistrar INTERNAL_CATCH_UNIQUE_NAME( catch_internal_ExceptionRegistrar )( &translatorName ); }\ static std::string translatorName( signature ) #define INTERNAL_CATCH_TRANSLATE_EXCEPTION( signature ) INTERNAL_CATCH_TRANSLATE_EXCEPTION2( INTERNAL_CATCH_UNIQUE_NAME( catch_internal_ExceptionTranslator ), signature ) #endif // TWOBLUECUBES_CATCH_INTERFACES_EXCEPTION_H_INCLUDED catch-1.12.1/include/internal/catch_interfaces_generators.h000066400000000000000000000016561325474075300240260ustar00rootroot00000000000000/* * Created by Phil on 7/8/2012. * Copyright 2011 Two Blue Cubes Ltd. All rights reserved. * * Distributed under the Boost Software License, Version 1.0. (See accompanying * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) */ #ifndef TWOBLUECUBES_CATCH_INTERFACES_GENERATORS_H_INCLUDED #define TWOBLUECUBES_CATCH_INTERFACES_GENERATORS_H_INCLUDED #include namespace Catch { struct IGeneratorInfo { virtual ~IGeneratorInfo(); virtual bool moveNext() = 0; virtual std::size_t getCurrentIndex() const = 0; }; struct IGeneratorsForTest { virtual ~IGeneratorsForTest(); virtual IGeneratorInfo& getGeneratorInfo( std::string const& fileInfo, std::size_t size ) = 0; virtual bool moveNext() = 0; }; IGeneratorsForTest* createGeneratorsForTest(); } // end namespace Catch #endif // TWOBLUECUBES_CATCH_INTERFACES_GENERATORS_H_INCLUDED catch-1.12.1/include/internal/catch_interfaces_registry_hub.h000066400000000000000000000034171325474075300243600ustar00rootroot00000000000000/* * Created by Phil on 5/8/2012. * Copyright 2012 Two Blue Cubes Ltd. All rights reserved. * * Distributed under the Boost Software License, Version 1.0. (See accompanying * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) */ #ifndef TWOBLUECUBES_CATCH_INTERFACES_REGISTRY_HUB_H_INCLUDED #define TWOBLUECUBES_CATCH_INTERFACES_REGISTRY_HUB_H_INCLUDED #include "catch_ptr.hpp" #include namespace Catch { class TestCase; struct ITestCaseRegistry; struct IExceptionTranslatorRegistry; struct IExceptionTranslator; struct IReporterRegistry; struct IReporterFactory; struct ITagAliasRegistry; struct IRegistryHub { virtual ~IRegistryHub(); virtual IReporterRegistry const& getReporterRegistry() const = 0; virtual ITestCaseRegistry const& getTestCaseRegistry() const = 0; virtual ITagAliasRegistry const& getTagAliasRegistry() const = 0; virtual IExceptionTranslatorRegistry& getExceptionTranslatorRegistry() = 0; }; struct IMutableRegistryHub { virtual ~IMutableRegistryHub(); virtual void registerReporter( std::string const& name, Ptr const& factory ) = 0; virtual void registerListener( Ptr const& factory ) = 0; virtual void registerTest( TestCase const& testInfo ) = 0; virtual void registerTranslator( const IExceptionTranslator* translator ) = 0; virtual void registerTagAlias( std::string const& alias, std::string const& tag, SourceLineInfo const& lineInfo ) = 0; }; IRegistryHub& getRegistryHub(); IMutableRegistryHub& getMutableRegistryHub(); void cleanUp(); std::string translateActiveException(); } #endif // TWOBLUECUBES_CATCH_INTERFACES_REGISTRY_HUB_H_INCLUDED catch-1.12.1/include/internal/catch_interfaces_reporter.h000066400000000000000000000226041325474075300235130ustar00rootroot00000000000000/* * Created by Phil on 31/12/2010. * Copyright 2010 Two Blue Cubes Ltd. All rights reserved. * * Distributed under the Boost Software License, Version 1.0. (See accompanying * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) */ #ifndef TWOBLUECUBES_CATCH_INTERFACES_REPORTER_H_INCLUDED #define TWOBLUECUBES_CATCH_INTERFACES_REPORTER_H_INCLUDED #include "catch_section_info.h" #include "catch_common.h" #include "catch_totals.hpp" #include "catch_ptr.hpp" #include "catch_config.hpp" #include "catch_test_case_info.h" #include "catch_assertionresult.h" #include "catch_message.h" #include "catch_option.hpp" #include #include #include namespace Catch { struct ReporterConfig { explicit ReporterConfig( Ptr const& _fullConfig ) : m_stream( &_fullConfig->stream() ), m_fullConfig( _fullConfig ) {} ReporterConfig( Ptr const& _fullConfig, std::ostream& _stream ) : m_stream( &_stream ), m_fullConfig( _fullConfig ) {} std::ostream& stream() const { return *m_stream; } Ptr fullConfig() const { return m_fullConfig; } private: std::ostream* m_stream; Ptr m_fullConfig; }; struct ReporterPreferences { ReporterPreferences() : shouldRedirectStdOut( false ) {} bool shouldRedirectStdOut; }; template struct LazyStat : Option { LazyStat() : used( false ) {} LazyStat& operator=( T const& _value ) { Option::operator=( _value ); used = false; return *this; } void reset() { Option::reset(); used = false; } bool used; }; struct TestRunInfo { TestRunInfo( std::string const& _name ) : name( _name ) {} std::string name; }; struct GroupInfo { GroupInfo( std::string const& _name, std::size_t _groupIndex, std::size_t _groupsCount ) : name( _name ), groupIndex( _groupIndex ), groupsCounts( _groupsCount ) {} std::string name; std::size_t groupIndex; std::size_t groupsCounts; }; struct AssertionStats { AssertionStats( AssertionResult const& _assertionResult, std::vector const& _infoMessages, Totals const& _totals ) : assertionResult( _assertionResult ), infoMessages( _infoMessages ), totals( _totals ) { if( assertionResult.hasMessage() ) { // Copy message into messages list. // !TBD This should have been done earlier, somewhere MessageBuilder builder( assertionResult.getTestMacroName(), assertionResult.getSourceInfo(), assertionResult.getResultType() ); builder << assertionResult.getMessage(); builder.m_info.message = builder.m_stream.str(); infoMessages.push_back( builder.m_info ); } } virtual ~AssertionStats(); # ifdef CATCH_CONFIG_CPP11_GENERATED_METHODS AssertionStats( AssertionStats const& ) = default; AssertionStats( AssertionStats && ) = default; AssertionStats& operator = ( AssertionStats const& ) = default; AssertionStats& operator = ( AssertionStats && ) = default; # endif AssertionResult assertionResult; std::vector infoMessages; Totals totals; }; struct SectionStats { SectionStats( SectionInfo const& _sectionInfo, Counts const& _assertions, double _durationInSeconds, bool _missingAssertions ) : sectionInfo( _sectionInfo ), assertions( _assertions ), durationInSeconds( _durationInSeconds ), missingAssertions( _missingAssertions ) {} virtual ~SectionStats(); # ifdef CATCH_CONFIG_CPP11_GENERATED_METHODS SectionStats( SectionStats const& ) = default; SectionStats( SectionStats && ) = default; SectionStats& operator = ( SectionStats const& ) = default; SectionStats& operator = ( SectionStats && ) = default; # endif SectionInfo sectionInfo; Counts assertions; double durationInSeconds; bool missingAssertions; }; struct TestCaseStats { TestCaseStats( TestCaseInfo const& _testInfo, Totals const& _totals, std::string const& _stdOut, std::string const& _stdErr, bool _aborting ) : testInfo( _testInfo ), totals( _totals ), stdOut( _stdOut ), stdErr( _stdErr ), aborting( _aborting ) {} virtual ~TestCaseStats(); # ifdef CATCH_CONFIG_CPP11_GENERATED_METHODS TestCaseStats( TestCaseStats const& ) = default; TestCaseStats( TestCaseStats && ) = default; TestCaseStats& operator = ( TestCaseStats const& ) = default; TestCaseStats& operator = ( TestCaseStats && ) = default; # endif TestCaseInfo testInfo; Totals totals; std::string stdOut; std::string stdErr; bool aborting; }; struct TestGroupStats { TestGroupStats( GroupInfo const& _groupInfo, Totals const& _totals, bool _aborting ) : groupInfo( _groupInfo ), totals( _totals ), aborting( _aborting ) {} TestGroupStats( GroupInfo const& _groupInfo ) : groupInfo( _groupInfo ), aborting( false ) {} virtual ~TestGroupStats(); # ifdef CATCH_CONFIG_CPP11_GENERATED_METHODS TestGroupStats( TestGroupStats const& ) = default; TestGroupStats( TestGroupStats && ) = default; TestGroupStats& operator = ( TestGroupStats const& ) = default; TestGroupStats& operator = ( TestGroupStats && ) = default; # endif GroupInfo groupInfo; Totals totals; bool aborting; }; struct TestRunStats { TestRunStats( TestRunInfo const& _runInfo, Totals const& _totals, bool _aborting ) : runInfo( _runInfo ), totals( _totals ), aborting( _aborting ) {} virtual ~TestRunStats(); # ifndef CATCH_CONFIG_CPP11_GENERATED_METHODS TestRunStats( TestRunStats const& _other ) : runInfo( _other.runInfo ), totals( _other.totals ), aborting( _other.aborting ) {} # else TestRunStats( TestRunStats const& ) = default; TestRunStats( TestRunStats && ) = default; TestRunStats& operator = ( TestRunStats const& ) = default; TestRunStats& operator = ( TestRunStats && ) = default; # endif TestRunInfo runInfo; Totals totals; bool aborting; }; class MultipleReporters; struct IStreamingReporter : IShared { virtual ~IStreamingReporter(); // Implementing class must also provide the following static method: // static std::string getDescription(); virtual ReporterPreferences getPreferences() const = 0; virtual void noMatchingTestCases( std::string const& spec ) = 0; virtual void testRunStarting( TestRunInfo const& testRunInfo ) = 0; virtual void testGroupStarting( GroupInfo const& groupInfo ) = 0; virtual void testCaseStarting( TestCaseInfo const& testInfo ) = 0; virtual void sectionStarting( SectionInfo const& sectionInfo ) = 0; virtual void assertionStarting( AssertionInfo const& assertionInfo ) = 0; // The return value indicates if the messages buffer should be cleared: virtual bool assertionEnded( AssertionStats const& assertionStats ) = 0; virtual void sectionEnded( SectionStats const& sectionStats ) = 0; virtual void testCaseEnded( TestCaseStats const& testCaseStats ) = 0; virtual void testGroupEnded( TestGroupStats const& testGroupStats ) = 0; virtual void testRunEnded( TestRunStats const& testRunStats ) = 0; virtual void skipTest( TestCaseInfo const& testInfo ) = 0; virtual MultipleReporters* tryAsMulti() { return CATCH_NULL; } }; struct IReporterFactory : IShared { virtual ~IReporterFactory(); virtual IStreamingReporter* create( ReporterConfig const& config ) const = 0; virtual std::string getDescription() const = 0; }; struct IReporterRegistry { typedef std::map > FactoryMap; typedef std::vector > Listeners; virtual ~IReporterRegistry(); virtual IStreamingReporter* create( std::string const& name, Ptr const& config ) const = 0; virtual FactoryMap const& getFactories() const = 0; virtual Listeners const& getListeners() const = 0; }; Ptr addReporter( Ptr const& existingReporter, Ptr const& additionalReporter ); } #endif // TWOBLUECUBES_CATCH_INTERFACES_REPORTER_H_INCLUDED catch-1.12.1/include/internal/catch_interfaces_runner.h000066400000000000000000000010741325474075300231600ustar00rootroot00000000000000/* * Created by Phil on 07/01/2011. * Copyright 2011 Two Blue Cubes Ltd. All rights reserved. * * Distributed under the Boost Software License, Version 1.0. (See accompanying * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) */ #ifndef TWOBLUECUBES_CATCH_INTERFACES_RUNNER_H_INCLUDED #define TWOBLUECUBES_CATCH_INTERFACES_RUNNER_H_INCLUDED namespace Catch { class TestCase; struct IRunner { virtual ~IRunner(); virtual bool aborting() const = 0; }; } #endif // TWOBLUECUBES_CATCH_INTERFACES_RUNNER_H_INCLUDED catch-1.12.1/include/internal/catch_interfaces_tag_alias_registry.h000066400000000000000000000015411325474075300255220ustar00rootroot00000000000000/* * Created by Phil on 27/6/2014. * Copyright 2014 Two Blue Cubes Ltd. All rights reserved. * * Distributed under the Boost Software License, Version 1.0. (See accompanying * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) */ #ifndef TWOBLUECUBES_CATCH_INTERFACES_TAG_ALIAS_REGISTRY_H_INCLUDED #define TWOBLUECUBES_CATCH_INTERFACES_TAG_ALIAS_REGISTRY_H_INCLUDED #include "catch_tag_alias.h" #include "catch_option.hpp" namespace Catch { struct ITagAliasRegistry { virtual ~ITagAliasRegistry(); virtual Option find( std::string const& alias ) const = 0; virtual std::string expandAliases( std::string const& unexpandedTestSpec ) const = 0; static ITagAliasRegistry const& get(); }; } // end namespace Catch #endif // TWOBLUECUBES_CATCH_INTERFACES_TAG_ALIAS_REGISTRY_H_INCLUDED catch-1.12.1/include/internal/catch_interfaces_testcase.h000066400000000000000000000023411325474075300234600ustar00rootroot00000000000000/* * Created by Phil on 07/01/2011. * Copyright 2011 Two Blue Cubes Ltd. All rights reserved. * * Distributed under the Boost Software License, Version 1.0. (See accompanying * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) */ #ifndef TWOBLUECUBES_CATCH_INTERFACES_TESTCASE_H_INCLUDED #define TWOBLUECUBES_CATCH_INTERFACES_TESTCASE_H_INCLUDED #include "catch_ptr.hpp" #include namespace Catch { class TestSpec; struct ITestCase : IShared { virtual void invoke () const = 0; protected: virtual ~ITestCase(); }; class TestCase; struct IConfig; struct ITestCaseRegistry { virtual ~ITestCaseRegistry(); virtual std::vector const& getAllTests() const = 0; virtual std::vector const& getAllTestsSorted( IConfig const& config ) const = 0; }; bool matchTest( TestCase const& testCase, TestSpec const& testSpec, IConfig const& config ); std::vector filterTests( std::vector const& testCases, TestSpec const& testSpec, IConfig const& config ); std::vector const& getAllTestCasesSorted( IConfig const& config ); } #endif // TWOBLUECUBES_CATCH_INTERFACES_TESTCASE_H_INCLUDED catch-1.12.1/include/internal/catch_legacy_reporter_adapter.h000066400000000000000000000053031325474075300243310ustar00rootroot00000000000000/* * Created by Phil on 6th April 2013. * Copyright 2013 Two Blue Cubes Ltd. All rights reserved. * * Distributed under the Boost Software License, Version 1.0. (See accompanying * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) */ #ifndef TWOBLUECUBES_CATCH_LEGACY_REPORTER_ADAPTER_H_INCLUDED #define TWOBLUECUBES_CATCH_LEGACY_REPORTER_ADAPTER_H_INCLUDED #include "catch_interfaces_reporter.h" namespace Catch { // Deprecated struct IReporter : IShared { virtual ~IReporter(); virtual bool shouldRedirectStdout() const = 0; virtual void StartTesting() = 0; virtual void EndTesting( Totals const& totals ) = 0; virtual void StartGroup( std::string const& groupName ) = 0; virtual void EndGroup( std::string const& groupName, Totals const& totals ) = 0; virtual void StartTestCase( TestCaseInfo const& testInfo ) = 0; virtual void EndTestCase( TestCaseInfo const& testInfo, Totals const& totals, std::string const& stdOut, std::string const& stdErr ) = 0; virtual void StartSection( std::string const& sectionName, std::string const& description ) = 0; virtual void EndSection( std::string const& sectionName, Counts const& assertions ) = 0; virtual void NoAssertionsInSection( std::string const& sectionName ) = 0; virtual void NoAssertionsInTestCase( std::string const& testName ) = 0; virtual void Aborted() = 0; virtual void Result( AssertionResult const& result ) = 0; }; class LegacyReporterAdapter : public SharedImpl { public: LegacyReporterAdapter( Ptr const& legacyReporter ); virtual ~LegacyReporterAdapter(); virtual ReporterPreferences getPreferences() const; virtual void noMatchingTestCases( std::string const& ); virtual void testRunStarting( TestRunInfo const& ); virtual void testGroupStarting( GroupInfo const& groupInfo ); virtual void testCaseStarting( TestCaseInfo const& testInfo ); virtual void sectionStarting( SectionInfo const& sectionInfo ); virtual void assertionStarting( AssertionInfo const& ); virtual bool assertionEnded( AssertionStats const& assertionStats ); virtual void sectionEnded( SectionStats const& sectionStats ); virtual void testCaseEnded( TestCaseStats const& testCaseStats ); virtual void testGroupEnded( TestGroupStats const& testGroupStats ); virtual void testRunEnded( TestRunStats const& testRunStats ); virtual void skipTest( TestCaseInfo const& ); private: Ptr m_legacyReporter; }; } #endif // TWOBLUECUBES_CATCH_LEGACY_REPORTER_ADAPTER_H_INCLUDED catch-1.12.1/include/internal/catch_legacy_reporter_adapter.hpp000066400000000000000000000071361325474075300246770ustar00rootroot00000000000000/* * Created by Phil on 6th April 2013. * Copyright 2013 Two Blue Cubes Ltd. All rights reserved. * * Distributed under the Boost Software License, Version 1.0. (See accompanying * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) */ #ifndef TWOBLUECUBES_CATCH_LEGACY_REPORTER_ADAPTER_HPP_INCLUDED #define TWOBLUECUBES_CATCH_LEGACY_REPORTER_ADAPTER_HPP_INCLUDED #include "catch_legacy_reporter_adapter.h" namespace Catch { LegacyReporterAdapter::LegacyReporterAdapter( Ptr const& legacyReporter ) : m_legacyReporter( legacyReporter ) {} LegacyReporterAdapter::~LegacyReporterAdapter() {} ReporterPreferences LegacyReporterAdapter::getPreferences() const { ReporterPreferences prefs; prefs.shouldRedirectStdOut = m_legacyReporter->shouldRedirectStdout(); return prefs; } void LegacyReporterAdapter::noMatchingTestCases( std::string const& ) {} void LegacyReporterAdapter::testRunStarting( TestRunInfo const& ) { m_legacyReporter->StartTesting(); } void LegacyReporterAdapter::testGroupStarting( GroupInfo const& groupInfo ) { m_legacyReporter->StartGroup( groupInfo.name ); } void LegacyReporterAdapter::testCaseStarting( TestCaseInfo const& testInfo ) { m_legacyReporter->StartTestCase( testInfo ); } void LegacyReporterAdapter::sectionStarting( SectionInfo const& sectionInfo ) { m_legacyReporter->StartSection( sectionInfo.name, sectionInfo.description ); } void LegacyReporterAdapter::assertionStarting( AssertionInfo const& ) { // Not on legacy interface } bool LegacyReporterAdapter::assertionEnded( AssertionStats const& assertionStats ) { if( assertionStats.assertionResult.getResultType() != ResultWas::Ok ) { for( std::vector::const_iterator it = assertionStats.infoMessages.begin(), itEnd = assertionStats.infoMessages.end(); it != itEnd; ++it ) { if( it->type == ResultWas::Info ) { ResultBuilder rb( it->macroName.c_str(), it->lineInfo, "", ResultDisposition::Normal ); rb << it->message; rb.setResultType( ResultWas::Info ); AssertionResult result = rb.build(); m_legacyReporter->Result( result ); } } } m_legacyReporter->Result( assertionStats.assertionResult ); return true; } void LegacyReporterAdapter::sectionEnded( SectionStats const& sectionStats ) { if( sectionStats.missingAssertions ) m_legacyReporter->NoAssertionsInSection( sectionStats.sectionInfo.name ); m_legacyReporter->EndSection( sectionStats.sectionInfo.name, sectionStats.assertions ); } void LegacyReporterAdapter::testCaseEnded( TestCaseStats const& testCaseStats ) { m_legacyReporter->EndTestCase ( testCaseStats.testInfo, testCaseStats.totals, testCaseStats.stdOut, testCaseStats.stdErr ); } void LegacyReporterAdapter::testGroupEnded( TestGroupStats const& testGroupStats ) { if( testGroupStats.aborting ) m_legacyReporter->Aborted(); m_legacyReporter->EndGroup( testGroupStats.groupInfo.name, testGroupStats.totals ); } void LegacyReporterAdapter::testRunEnded( TestRunStats const& testRunStats ) { m_legacyReporter->EndTesting( testRunStats.totals ); } void LegacyReporterAdapter::skipTest( TestCaseInfo const& ) { } } #endif // TWOBLUECUBES_CATCH_LEGACY_REPORTER_ADAPTER_H_INCLUDED catch-1.12.1/include/internal/catch_list.hpp000066400000000000000000000203561325474075300207630ustar00rootroot00000000000000/* * Created by Phil on 5/11/2010. * Copyright 2010 Two Blue Cubes Ltd. All rights reserved. * * Distributed under the Boost Software License, Version 1.0. (See accompanying * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) */ #ifndef TWOBLUECUBES_CATCH_LIST_HPP_INCLUDED #define TWOBLUECUBES_CATCH_LIST_HPP_INCLUDED #include "catch_commandline.hpp" #include "catch_text.h" #include "catch_console_colour.hpp" #include "catch_interfaces_reporter.h" #include "catch_test_spec_parser.hpp" #include #include namespace Catch { inline std::size_t listTests( Config const& config ) { TestSpec testSpec = config.testSpec(); if( config.testSpec().hasFilters() ) Catch::cout() << "Matching test cases:\n"; else { Catch::cout() << "All available test cases:\n"; testSpec = TestSpecParser( ITagAliasRegistry::get() ).parse( "*" ).testSpec(); } std::size_t matchedTests = 0; TextAttributes nameAttr, descAttr, tagsAttr; nameAttr.setInitialIndent( 2 ).setIndent( 4 ); descAttr.setIndent( 4 ); tagsAttr.setIndent( 6 ); std::vector matchedTestCases = filterTests( getAllTestCasesSorted( config ), testSpec, config ); for( std::vector::const_iterator it = matchedTestCases.begin(), itEnd = matchedTestCases.end(); it != itEnd; ++it ) { matchedTests++; TestCaseInfo const& testCaseInfo = it->getTestCaseInfo(); Colour::Code colour = testCaseInfo.isHidden() ? Colour::SecondaryText : Colour::None; Colour colourGuard( colour ); Catch::cout() << Text( testCaseInfo.name, nameAttr ) << std::endl; if( config.listExtraInfo() ) { Catch::cout() << " " << testCaseInfo.lineInfo << std::endl; std::string description = testCaseInfo.description; if( description.empty() ) description = "(NO DESCRIPTION)"; Catch::cout() << Text( description, descAttr ) << std::endl; } if( !testCaseInfo.tags.empty() ) Catch::cout() << Text( testCaseInfo.tagsAsString, tagsAttr ) << std::endl; } if( !config.testSpec().hasFilters() ) Catch::cout() << pluralise( matchedTests, "test case" ) << '\n' << std::endl; else Catch::cout() << pluralise( matchedTests, "matching test case" ) << '\n' << std::endl; return matchedTests; } inline std::size_t listTestsNamesOnly( Config const& config ) { TestSpec testSpec = config.testSpec(); if( !config.testSpec().hasFilters() ) testSpec = TestSpecParser( ITagAliasRegistry::get() ).parse( "*" ).testSpec(); std::size_t matchedTests = 0; std::vector matchedTestCases = filterTests( getAllTestCasesSorted( config ), testSpec, config ); for( std::vector::const_iterator it = matchedTestCases.begin(), itEnd = matchedTestCases.end(); it != itEnd; ++it ) { matchedTests++; TestCaseInfo const& testCaseInfo = it->getTestCaseInfo(); if( startsWith( testCaseInfo.name, '#' ) ) Catch::cout() << '"' << testCaseInfo.name << '"'; else Catch::cout() << testCaseInfo.name; if ( config.listExtraInfo() ) Catch::cout() << "\t@" << testCaseInfo.lineInfo; Catch::cout() << std::endl; } return matchedTests; } struct TagInfo { TagInfo() : count ( 0 ) {} void add( std::string const& spelling ) { ++count; spellings.insert( spelling ); } std::string all() const { std::string out; for( std::set::const_iterator it = spellings.begin(), itEnd = spellings.end(); it != itEnd; ++it ) out += "[" + *it + "]"; return out; } std::set spellings; std::size_t count; }; inline std::size_t listTags( Config const& config ) { TestSpec testSpec = config.testSpec(); if( config.testSpec().hasFilters() ) Catch::cout() << "Tags for matching test cases:\n"; else { Catch::cout() << "All available tags:\n"; testSpec = TestSpecParser( ITagAliasRegistry::get() ).parse( "*" ).testSpec(); } std::map tagCounts; std::vector matchedTestCases = filterTests( getAllTestCasesSorted( config ), testSpec, config ); for( std::vector::const_iterator it = matchedTestCases.begin(), itEnd = matchedTestCases.end(); it != itEnd; ++it ) { for( std::set::const_iterator tagIt = it->getTestCaseInfo().tags.begin(), tagItEnd = it->getTestCaseInfo().tags.end(); tagIt != tagItEnd; ++tagIt ) { std::string tagName = *tagIt; std::string lcaseTagName = toLower( tagName ); std::map::iterator countIt = tagCounts.find( lcaseTagName ); if( countIt == tagCounts.end() ) countIt = tagCounts.insert( std::make_pair( lcaseTagName, TagInfo() ) ).first; countIt->second.add( tagName ); } } for( std::map::const_iterator countIt = tagCounts.begin(), countItEnd = tagCounts.end(); countIt != countItEnd; ++countIt ) { std::ostringstream oss; oss << " " << std::setw(2) << countIt->second.count << " "; Text wrapper( countIt->second.all(), TextAttributes() .setInitialIndent( 0 ) .setIndent( oss.str().size() ) .setWidth( CATCH_CONFIG_CONSOLE_WIDTH-10 ) ); Catch::cout() << oss.str() << wrapper << '\n'; } Catch::cout() << pluralise( tagCounts.size(), "tag" ) << '\n' << std::endl; return tagCounts.size(); } inline std::size_t listReporters( Config const& /*config*/ ) { Catch::cout() << "Available reporters:\n"; IReporterRegistry::FactoryMap const& factories = getRegistryHub().getReporterRegistry().getFactories(); IReporterRegistry::FactoryMap::const_iterator itBegin = factories.begin(), itEnd = factories.end(), it; std::size_t maxNameLen = 0; for(it = itBegin; it != itEnd; ++it ) maxNameLen = (std::max)( maxNameLen, it->first.size() ); for(it = itBegin; it != itEnd; ++it ) { Text wrapper( it->second->getDescription(), TextAttributes() .setInitialIndent( 0 ) .setIndent( 7+maxNameLen ) .setWidth( CATCH_CONFIG_CONSOLE_WIDTH - maxNameLen-8 ) ); Catch::cout() << " " << it->first << ':' << std::string( maxNameLen - it->first.size() + 2, ' ' ) << wrapper << '\n'; } Catch::cout() << std::endl; return factories.size(); } inline Option list( Config const& config ) { Option listedCount; if( config.listTests() || ( config.listExtraInfo() && !config.listTestNamesOnly() ) ) listedCount = listedCount.valueOr(0) + listTests( config ); if( config.listTestNamesOnly() ) listedCount = listedCount.valueOr(0) + listTestsNamesOnly( config ); if( config.listTags() ) listedCount = listedCount.valueOr(0) + listTags( config ); if( config.listReporters() ) listedCount = listedCount.valueOr(0) + listReporters( config ); return listedCount; } } // end namespace Catch #endif // TWOBLUECUBES_CATCH_LIST_HPP_INCLUDED catch-1.12.1/include/internal/catch_matchers.hpp000066400000000000000000000147571325474075300216260ustar00rootroot00000000000000/* * Created by Phil Nash on 04/03/2012. * Copyright (c) 2012 Two Blue Cubes Ltd. All rights reserved. * * Distributed under the Boost Software License, Version 1.0. (See accompanying * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) */ #ifndef TWOBLUECUBES_CATCH_MATCHERS_HPP_INCLUDED #define TWOBLUECUBES_CATCH_MATCHERS_HPP_INCLUDED #include "catch_common.h" namespace Catch { namespace Matchers { namespace Impl { template struct MatchAllOf; template struct MatchAnyOf; template struct MatchNotOf; class MatcherUntypedBase { public: std::string toString() const { if( m_cachedToString.empty() ) m_cachedToString = describe(); return m_cachedToString; } protected: virtual ~MatcherUntypedBase(); virtual std::string describe() const = 0; mutable std::string m_cachedToString; private: MatcherUntypedBase& operator = ( MatcherUntypedBase const& ); }; template struct MatcherMethod { virtual bool match( ObjectT const& arg ) const = 0; }; template struct MatcherMethod { virtual bool match( PtrT* arg ) const = 0; }; template struct MatcherBase : MatcherUntypedBase, MatcherMethod { MatchAllOf operator && ( MatcherBase const& other ) const; MatchAnyOf operator || ( MatcherBase const& other ) const; MatchNotOf operator ! () const; }; template struct MatchAllOf : MatcherBase { virtual bool match( ArgT const& arg ) const CATCH_OVERRIDE { for( std::size_t i = 0; i < m_matchers.size(); ++i ) { if (!m_matchers[i]->match(arg)) return false; } return true; } virtual std::string describe() const CATCH_OVERRIDE { std::string description; description.reserve( 4 + m_matchers.size()*32 ); description += "( "; for( std::size_t i = 0; i < m_matchers.size(); ++i ) { if( i != 0 ) description += " and "; description += m_matchers[i]->toString(); } description += " )"; return description; } MatchAllOf& operator && ( MatcherBase const& other ) { m_matchers.push_back( &other ); return *this; } std::vector const*> m_matchers; }; template struct MatchAnyOf : MatcherBase { virtual bool match( ArgT const& arg ) const CATCH_OVERRIDE { for( std::size_t i = 0; i < m_matchers.size(); ++i ) { if (m_matchers[i]->match(arg)) return true; } return false; } virtual std::string describe() const CATCH_OVERRIDE { std::string description; description.reserve( 4 + m_matchers.size()*32 ); description += "( "; for( std::size_t i = 0; i < m_matchers.size(); ++i ) { if( i != 0 ) description += " or "; description += m_matchers[i]->toString(); } description += " )"; return description; } MatchAnyOf& operator || ( MatcherBase const& other ) { m_matchers.push_back( &other ); return *this; } std::vector const*> m_matchers; }; template struct MatchNotOf : MatcherBase { MatchNotOf( MatcherBase const& underlyingMatcher ) : m_underlyingMatcher( underlyingMatcher ) {} virtual bool match( ArgT const& arg ) const CATCH_OVERRIDE { return !m_underlyingMatcher.match( arg ); } virtual std::string describe() const CATCH_OVERRIDE { return "not " + m_underlyingMatcher.toString(); } MatcherBase const& m_underlyingMatcher; }; template MatchAllOf MatcherBase::operator && ( MatcherBase const& other ) const { return MatchAllOf() && *this && other; } template MatchAnyOf MatcherBase::operator || ( MatcherBase const& other ) const { return MatchAnyOf() || *this || other; } template MatchNotOf MatcherBase::operator ! () const { return MatchNotOf( *this ); } } // namespace Impl // The following functions create the actual matcher objects. // This allows the types to be inferred // - deprecated: prefer ||, && and ! template Impl::MatchNotOf Not( Impl::MatcherBase const& underlyingMatcher ) { return Impl::MatchNotOf( underlyingMatcher ); } template Impl::MatchAllOf AllOf( Impl::MatcherBase const& m1, Impl::MatcherBase const& m2 ) { return Impl::MatchAllOf() && m1 && m2; } template Impl::MatchAllOf AllOf( Impl::MatcherBase const& m1, Impl::MatcherBase const& m2, Impl::MatcherBase const& m3 ) { return Impl::MatchAllOf() && m1 && m2 && m3; } template Impl::MatchAnyOf AnyOf( Impl::MatcherBase const& m1, Impl::MatcherBase const& m2 ) { return Impl::MatchAnyOf() || m1 || m2; } template Impl::MatchAnyOf AnyOf( Impl::MatcherBase const& m1, Impl::MatcherBase const& m2, Impl::MatcherBase const& m3 ) { return Impl::MatchAnyOf() || m1 || m2 || m3; } } // namespace Matchers using namespace Matchers; using Matchers::Impl::MatcherBase; } // namespace Catch #endif // TWOBLUECUBES_CATCH_MATCHERS_HPP_INCLUDED catch-1.12.1/include/internal/catch_matchers_string.h000066400000000000000000000052361325474075300226440ustar00rootroot00000000000000/* * Created by Phil Nash on 08/02/2017. * Copyright (c) 2017 Two Blue Cubes Ltd. All rights reserved. * * Distributed under the Boost Software License, Version 1.0. (See accompanying * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) */ #ifndef TWOBLUECUBES_CATCH_MATCHERS_STRING_H_INCLUDED #define TWOBLUECUBES_CATCH_MATCHERS_STRING_H_INCLUDED #include "catch_matchers.hpp" namespace Catch { namespace Matchers { namespace StdString { struct CasedString { CasedString( std::string const& str, CaseSensitive::Choice caseSensitivity ); std::string adjustString( std::string const& str ) const; std::string caseSensitivitySuffix() const; CaseSensitive::Choice m_caseSensitivity; std::string m_str; }; struct StringMatcherBase : MatcherBase { StringMatcherBase( std::string const& operation, CasedString const& comparator ); virtual std::string describe() const CATCH_OVERRIDE; CasedString m_comparator; std::string m_operation; }; struct EqualsMatcher : StringMatcherBase { EqualsMatcher( CasedString const& comparator ); virtual bool match( std::string const& source ) const CATCH_OVERRIDE; }; struct ContainsMatcher : StringMatcherBase { ContainsMatcher( CasedString const& comparator ); virtual bool match( std::string const& source ) const CATCH_OVERRIDE; }; struct StartsWithMatcher : StringMatcherBase { StartsWithMatcher( CasedString const& comparator ); virtual bool match( std::string const& source ) const CATCH_OVERRIDE; }; struct EndsWithMatcher : StringMatcherBase { EndsWithMatcher( CasedString const& comparator ); virtual bool match( std::string const& source ) const CATCH_OVERRIDE; }; } // namespace StdString // The following functions create the actual matcher objects. // This allows the types to be inferred StdString::EqualsMatcher Equals( std::string const& str, CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes ); StdString::ContainsMatcher Contains( std::string const& str, CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes ); StdString::EndsWithMatcher EndsWith( std::string const& str, CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes ); StdString::StartsWithMatcher StartsWith( std::string const& str, CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes ); } // namespace Matchers } // namespace Catch #endif // TWOBLUECUBES_CATCH_MATCHERS_STRING_H_INCLUDED catch-1.12.1/include/internal/catch_matchers_string.hpp000066400000000000000000000073171325474075300232060ustar00rootroot00000000000000/* * Created by Phil Nash on 08/02/2017. * Copyright (c) 2017 Two Blue Cubes Ltd. All rights reserved. * * Distributed under the Boost Software License, Version 1.0. (See accompanying * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) */ #include "catch_matchers.hpp" namespace Catch { namespace Matchers { namespace StdString { CasedString::CasedString( std::string const& str, CaseSensitive::Choice caseSensitivity ) : m_caseSensitivity( caseSensitivity ), m_str( adjustString( str ) ) {} std::string CasedString::adjustString( std::string const& str ) const { return m_caseSensitivity == CaseSensitive::No ? toLower( str ) : str; } std::string CasedString::caseSensitivitySuffix() const { return m_caseSensitivity == CaseSensitive::No ? " (case insensitive)" : std::string(); } StringMatcherBase::StringMatcherBase( std::string const& operation, CasedString const& comparator ) : m_comparator( comparator ), m_operation( operation ) { } std::string StringMatcherBase::describe() const { std::string description; description.reserve(5 + m_operation.size() + m_comparator.m_str.size() + m_comparator.caseSensitivitySuffix().size()); description += m_operation; description += ": \""; description += m_comparator.m_str; description += "\""; description += m_comparator.caseSensitivitySuffix(); return description; } EqualsMatcher::EqualsMatcher( CasedString const& comparator ) : StringMatcherBase( "equals", comparator ) {} bool EqualsMatcher::match( std::string const& source ) const { return m_comparator.adjustString( source ) == m_comparator.m_str; } ContainsMatcher::ContainsMatcher( CasedString const& comparator ) : StringMatcherBase( "contains", comparator ) {} bool ContainsMatcher::match( std::string const& source ) const { return contains( m_comparator.adjustString( source ), m_comparator.m_str ); } StartsWithMatcher::StartsWithMatcher( CasedString const& comparator ) : StringMatcherBase( "starts with", comparator ) {} bool StartsWithMatcher::match( std::string const& source ) const { return startsWith( m_comparator.adjustString( source ), m_comparator.m_str ); } EndsWithMatcher::EndsWithMatcher( CasedString const& comparator ) : StringMatcherBase( "ends with", comparator ) {} bool EndsWithMatcher::match( std::string const& source ) const { return endsWith( m_comparator.adjustString( source ), m_comparator.m_str ); } } // namespace StdString StdString::EqualsMatcher Equals( std::string const& str, CaseSensitive::Choice caseSensitivity ) { return StdString::EqualsMatcher( StdString::CasedString( str, caseSensitivity) ); } StdString::ContainsMatcher Contains( std::string const& str, CaseSensitive::Choice caseSensitivity ) { return StdString::ContainsMatcher( StdString::CasedString( str, caseSensitivity) ); } StdString::EndsWithMatcher EndsWith( std::string const& str, CaseSensitive::Choice caseSensitivity ) { return StdString::EndsWithMatcher( StdString::CasedString( str, caseSensitivity) ); } StdString::StartsWithMatcher StartsWith( std::string const& str, CaseSensitive::Choice caseSensitivity ) { return StdString::StartsWithMatcher( StdString::CasedString( str, caseSensitivity) ); } } // namespace Matchers } // namespace Catch catch-1.12.1/include/internal/catch_matchers_vector.h000066400000000000000000000071501325474075300226350ustar00rootroot00000000000000/* * Created by Phil Nash on 21/02/2017. * Copyright (c) 2017 Two Blue Cubes Ltd. All rights reserved. * * Distributed under the Boost Software License, Version 1.0. (See accompanying * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) */ #ifndef TWOBLUECUBES_CATCH_MATCHERS_VECTOR_H_INCLUDED #define TWOBLUECUBES_CATCH_MATCHERS_VECTOR_H_INCLUDED #include "catch_matchers.hpp" namespace Catch { namespace Matchers { namespace Vector { template struct ContainsElementMatcher : MatcherBase, T> { ContainsElementMatcher(T const &comparator) : m_comparator( comparator) {} bool match(std::vector const &v) const CATCH_OVERRIDE { return std::find(v.begin(), v.end(), m_comparator) != v.end(); } virtual std::string describe() const CATCH_OVERRIDE { return "Contains: " + Catch::toString( m_comparator ); } T const& m_comparator; }; template struct ContainsMatcher : MatcherBase, std::vector > { ContainsMatcher(std::vector const &comparator) : m_comparator( comparator ) {} bool match(std::vector const &v) const CATCH_OVERRIDE { // !TBD: see note in EqualsMatcher if (m_comparator.size() > v.size()) return false; for (size_t i = 0; i < m_comparator.size(); ++i) if (std::find(v.begin(), v.end(), m_comparator[i]) == v.end()) return false; return true; } virtual std::string describe() const CATCH_OVERRIDE { return "Contains: " + Catch::toString( m_comparator ); } std::vector const& m_comparator; }; template struct EqualsMatcher : MatcherBase, std::vector > { EqualsMatcher(std::vector const &comparator) : m_comparator( comparator ) {} bool match(std::vector const &v) const CATCH_OVERRIDE { // !TBD: This currently works if all elements can be compared using != // - a more general approach would be via a compare template that defaults // to using !=. but could be specialised for, e.g. std::vector etc // - then just call that directly if (m_comparator.size() != v.size()) return false; for (size_t i = 0; i < v.size(); ++i) if (m_comparator[i] != v[i]) return false; return true; } virtual std::string describe() const CATCH_OVERRIDE { return "Equals: " + Catch::toString( m_comparator ); } std::vector const& m_comparator; }; } // namespace Vector // The following functions create the actual matcher objects. // This allows the types to be inferred template Vector::ContainsMatcher Contains( std::vector const& comparator ) { return Vector::ContainsMatcher( comparator ); } template Vector::ContainsElementMatcher VectorContains( T const& comparator ) { return Vector::ContainsElementMatcher( comparator ); } template Vector::EqualsMatcher Equals( std::vector const& comparator ) { return Vector::EqualsMatcher( comparator ); } } // namespace Matchers } // namespace Catch #endif // TWOBLUECUBES_CATCH_MATCHERS_VECTOR_H_INCLUDED catch-1.12.1/include/internal/catch_message.h000066400000000000000000000034731325474075300210750ustar00rootroot00000000000000/* * Created by Phil Nash on 1/2/2013. * Copyright 2013 Two Blue Cubes Ltd. All rights reserved. * * Distributed under the Boost Software License, Version 1.0. (See accompanying * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) */ #ifndef TWOBLUECUBES_CATCH_MESSAGE_H_INCLUDED #define TWOBLUECUBES_CATCH_MESSAGE_H_INCLUDED #include #include "catch_result_type.h" #include "catch_common.h" namespace Catch { struct MessageInfo { MessageInfo( std::string const& _macroName, SourceLineInfo const& _lineInfo, ResultWas::OfType _type ); std::string macroName; SourceLineInfo lineInfo; ResultWas::OfType type; std::string message; unsigned int sequence; bool operator == ( MessageInfo const& other ) const { return sequence == other.sequence; } bool operator < ( MessageInfo const& other ) const { return sequence < other.sequence; } private: static unsigned int globalCount; }; struct MessageBuilder { MessageBuilder( std::string const& macroName, SourceLineInfo const& lineInfo, ResultWas::OfType type ) : m_info( macroName, lineInfo, type ) {} template MessageBuilder& operator << ( T const& value ) { m_stream << value; return *this; } MessageInfo m_info; std::ostringstream m_stream; }; class ScopedMessage { public: ScopedMessage( MessageBuilder const& builder ); ScopedMessage( ScopedMessage const& other ); ~ScopedMessage(); MessageInfo m_info; }; } // end namespace Catch #endif // TWOBLUECUBES_CATCH_MESSAGE_H_INCLUDED catch-1.12.1/include/internal/catch_message.hpp000066400000000000000000000031521325474075300214270ustar00rootroot00000000000000/* * Created by Phil Nash on 1/2/2013. * Copyright 2013 Two Blue Cubes Ltd. All rights reserved. * * Distributed under the Boost Software License, Version 1.0. (See accompanying * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) */ #ifndef TWOBLUECUBES_CATCH_MESSAGE_HPP_INCLUDED #define TWOBLUECUBES_CATCH_MESSAGE_HPP_INCLUDED #include "catch_message.h" namespace Catch { MessageInfo::MessageInfo( std::string const& _macroName, SourceLineInfo const& _lineInfo, ResultWas::OfType _type ) : macroName( _macroName ), lineInfo( _lineInfo ), type( _type ), sequence( ++globalCount ) {} // This may need protecting if threading support is added unsigned int MessageInfo::globalCount = 0; //////////////////////////////////////////////////////////////////////////// ScopedMessage::ScopedMessage( MessageBuilder const& builder ) : m_info( builder.m_info ) { m_info.message = builder.m_stream.str(); getResultCapture().pushScopedMessage( m_info ); } ScopedMessage::ScopedMessage( ScopedMessage const& other ) : m_info( other.m_info ) {} #if defined(_MSC_VER) #pragma warning(push) #pragma warning(disable:4996) // std::uncaught_exception is deprecated in C++17 #endif ScopedMessage::~ScopedMessage() { if ( !std::uncaught_exception() ){ getResultCapture().popScopedMessage(m_info); } } #if defined(_MSC_VER) #pragma warning(pop) #endif } // end namespace Catch #endif // TWOBLUECUBES_CATCH_MESSAGE_HPP_INCLUDED catch-1.12.1/include/internal/catch_notimplemented_exception.h000066400000000000000000000020251325474075300245430ustar00rootroot00000000000000/* * Created by Phil on 5/8/2012. * Copyright 2012 Two Blue Cubes Ltd. All rights reserved. * * Distributed under the Boost Software License, Version 1.0. (See accompanying * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) */ #ifndef TWOBLUECUBES_CATCH_NOTIMPLEMENTED_EXCEPTION_H_INCLUDED #define TWOBLUECUBES_CATCH_NOTIMPLEMENTED_EXCEPTION_H_INCLUDED #include "catch_common.h" namespace Catch { class NotImplementedException : public std::exception { public: NotImplementedException( SourceLineInfo const& lineInfo ); virtual ~NotImplementedException() CATCH_NOEXCEPT {} virtual const char* what() const CATCH_NOEXCEPT; private: std::string m_what; SourceLineInfo m_lineInfo; }; } // end namespace Catch /////////////////////////////////////////////////////////////////////////////// #define CATCH_NOT_IMPLEMENTED throw Catch::NotImplementedException( CATCH_INTERNAL_LINEINFO ) #endif // TWOBLUECUBES_CATCH_NOTIMPLEMENTED_EXCEPTION_H_INCLUDED catch-1.12.1/include/internal/catch_notimplemented_exception.hpp000066400000000000000000000016511325474075300251070ustar00rootroot00000000000000/* * Created by Phil on 5/8/2012. * Copyright 2012 Two Blue Cubes Ltd. All rights reserved. * * Distributed under the Boost Software License, Version 1.0. (See accompanying * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) */ #ifndef TWOBLUECUBES_CATCH_NOTIMPLEMENTED_EXCEPTION_HPP_INCLUDED #define TWOBLUECUBES_CATCH_NOTIMPLEMENTED_EXCEPTION_HPP_INCLUDED #include "catch_notimplemented_exception.h" #include namespace Catch { NotImplementedException::NotImplementedException( SourceLineInfo const& lineInfo ) : m_lineInfo( lineInfo ) { std::ostringstream oss; oss << lineInfo << ": function "; oss << "not implemented"; m_what = oss.str(); } const char* NotImplementedException::what() const CATCH_NOEXCEPT { return m_what.c_str(); } } // end namespace Catch #endif // TWOBLUECUBES_CATCH_NOTIMPLEMENTED_EXCEPTION_HPP_INCLUDED catch-1.12.1/include/internal/catch_objc.hpp000066400000000000000000000162171325474075300207260ustar00rootroot00000000000000/* * Created by Phil on 14/11/2010. * Copyright 2010 Two Blue Cubes Ltd. All rights reserved. * * Distributed under the Boost Software License, Version 1.0. (See accompanying * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) */ #ifndef TWOBLUECUBES_CATCH_OBJC_HPP_INCLUDED #define TWOBLUECUBES_CATCH_OBJC_HPP_INCLUDED #include "catch_objc_arc.hpp" #import #include // NB. Any general catch headers included here must be included // in catch.hpp first to make sure they are included by the single // header for non obj-usage #include "catch_test_case_info.h" /////////////////////////////////////////////////////////////////////////////// // This protocol is really only here for (self) documenting purposes, since // all its methods are optional. @protocol OcFixture @optional -(void) setUp; -(void) tearDown; @end namespace Catch { class OcMethod : public SharedImpl { public: OcMethod( Class cls, SEL sel ) : m_cls( cls ), m_sel( sel ) {} virtual void invoke() const { id obj = [[m_cls alloc] init]; performOptionalSelector( obj, @selector(setUp) ); performOptionalSelector( obj, m_sel ); performOptionalSelector( obj, @selector(tearDown) ); arcSafeRelease( obj ); } private: virtual ~OcMethod() {} Class m_cls; SEL m_sel; }; namespace Detail{ inline std::string getAnnotation( Class cls, std::string const& annotationName, std::string const& testCaseName ) { NSString* selStr = [[NSString alloc] initWithFormat:@"Catch_%s_%s", annotationName.c_str(), testCaseName.c_str()]; SEL sel = NSSelectorFromString( selStr ); arcSafeRelease( selStr ); id value = performOptionalSelector( cls, sel ); if( value ) return [(NSString*)value UTF8String]; return ""; } } inline size_t registerTestMethods() { size_t noTestMethods = 0; int noClasses = objc_getClassList( CATCH_NULL, 0 ); Class* classes = (CATCH_UNSAFE_UNRETAINED Class *)malloc( sizeof(Class) * noClasses); objc_getClassList( classes, noClasses ); for( int c = 0; c < noClasses; c++ ) { Class cls = classes[c]; { u_int count; Method* methods = class_copyMethodList( cls, &count ); for( u_int m = 0; m < count ; m++ ) { SEL selector = method_getName(methods[m]); std::string methodName = sel_getName(selector); if( startsWith( methodName, "Catch_TestCase_" ) ) { std::string testCaseName = methodName.substr( 15 ); std::string name = Detail::getAnnotation( cls, "Name", testCaseName ); std::string desc = Detail::getAnnotation( cls, "Description", testCaseName ); const char* className = class_getName( cls ); getMutableRegistryHub().registerTest( makeTestCase( new OcMethod( cls, selector ), className, name.c_str(), desc.c_str(), SourceLineInfo() ) ); noTestMethods++; } } free(methods); } } return noTestMethods; } namespace Matchers { namespace Impl { namespace NSStringMatchers { struct StringHolder : MatcherBase{ StringHolder( NSString* substr ) : m_substr( [substr copy] ){} StringHolder( StringHolder const& other ) : m_substr( [other.m_substr copy] ){} StringHolder() { arcSafeRelease( m_substr ); } virtual bool match( NSString* arg ) const CATCH_OVERRIDE { return false; } NSString* m_substr; }; struct Equals : StringHolder { Equals( NSString* substr ) : StringHolder( substr ){} virtual bool match( NSString* str ) const CATCH_OVERRIDE { return (str != nil || m_substr == nil ) && [str isEqualToString:m_substr]; } virtual std::string describe() const CATCH_OVERRIDE { return "equals string: " + Catch::toString( m_substr ); } }; struct Contains : StringHolder { Contains( NSString* substr ) : StringHolder( substr ){} virtual bool match( NSString* str ) const { return (str != nil || m_substr == nil ) && [str rangeOfString:m_substr].location != NSNotFound; } virtual std::string describe() const CATCH_OVERRIDE { return "contains string: " + Catch::toString( m_substr ); } }; struct StartsWith : StringHolder { StartsWith( NSString* substr ) : StringHolder( substr ){} virtual bool match( NSString* str ) const { return (str != nil || m_substr == nil ) && [str rangeOfString:m_substr].location == 0; } virtual std::string describe() const CATCH_OVERRIDE { return "starts with: " + Catch::toString( m_substr ); } }; struct EndsWith : StringHolder { EndsWith( NSString* substr ) : StringHolder( substr ){} virtual bool match( NSString* str ) const { return (str != nil || m_substr == nil ) && [str rangeOfString:m_substr].location == [str length] - [m_substr length]; } virtual std::string describe() const CATCH_OVERRIDE { return "ends with: " + Catch::toString( m_substr ); } }; } // namespace NSStringMatchers } // namespace Impl inline Impl::NSStringMatchers::Equals Equals( NSString* substr ){ return Impl::NSStringMatchers::Equals( substr ); } inline Impl::NSStringMatchers::Contains Contains( NSString* substr ){ return Impl::NSStringMatchers::Contains( substr ); } inline Impl::NSStringMatchers::StartsWith StartsWith( NSString* substr ){ return Impl::NSStringMatchers::StartsWith( substr ); } inline Impl::NSStringMatchers::EndsWith EndsWith( NSString* substr ){ return Impl::NSStringMatchers::EndsWith( substr ); } } // namespace Matchers using namespace Matchers; } // namespace Catch /////////////////////////////////////////////////////////////////////////////// #define OC_TEST_CASE( name, desc )\ +(NSString*) INTERNAL_CATCH_UNIQUE_NAME( Catch_Name_test ) \ {\ return @ name; \ }\ +(NSString*) INTERNAL_CATCH_UNIQUE_NAME( Catch_Description_test ) \ { \ return @ desc; \ } \ -(void) INTERNAL_CATCH_UNIQUE_NAME( Catch_TestCase_test ) #endif // TWOBLUECUBES_CATCH_OBJC_HPP_INCLUDED catch-1.12.1/include/internal/catch_objc_arc.hpp000066400000000000000000000026061325474075300215500ustar00rootroot00000000000000/* * Created by Phil on 1/08/2012. * Copyright 2012 Two Blue Cubes Ltd. All rights reserved. * * Distributed under the Boost Software License, Version 1.0. (See accompanying * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) */ #ifndef TWOBLUECUBES_CATCH_OBJC_ARC_HPP_INCLUDED #define TWOBLUECUBES_CATCH_OBJC_ARC_HPP_INCLUDED #import #ifdef __has_feature #define CATCH_ARC_ENABLED __has_feature(objc_arc) #else #define CATCH_ARC_ENABLED 0 #endif void arcSafeRelease( NSObject* obj ); id performOptionalSelector( id obj, SEL sel ); #if !CATCH_ARC_ENABLED inline void arcSafeRelease( NSObject* obj ) { [obj release]; } inline id performOptionalSelector( id obj, SEL sel ) { if( [obj respondsToSelector: sel] ) return [obj performSelector: sel]; return nil; } #define CATCH_UNSAFE_UNRETAINED #define CATCH_ARC_STRONG #else inline void arcSafeRelease( NSObject* ){} inline id performOptionalSelector( id obj, SEL sel ) { #ifdef __clang__ #pragma clang diagnostic push #pragma clang diagnostic ignored "-Warc-performSelector-leaks" #endif if( [obj respondsToSelector: sel] ) return [obj performSelector: sel]; #ifdef __clang__ #pragma clang diagnostic pop #endif return nil; } #define CATCH_UNSAFE_UNRETAINED __unsafe_unretained #define CATCH_ARC_STRONG __strong #endif #endif // TWOBLUECUBES_CATCH_OBJC_ARC_HPP_INCLUDED catch-1.12.1/include/internal/catch_option.hpp000066400000000000000000000046251325474075300213210ustar00rootroot00000000000000/* * Created by Phil on 02/12/2012. * Copyright 2012 Two Blue Cubes Ltd. All rights reserved. * * Distributed under the Boost Software License, Version 1.0. (See accompanying * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) */ #ifndef TWOBLUECUBES_CATCH_OPTION_HPP_INCLUDED #define TWOBLUECUBES_CATCH_OPTION_HPP_INCLUDED #include "catch_common.h" namespace Catch { // An optional type template class Option { public: Option() : nullableValue( CATCH_NULL ) {} Option( T const& _value ) : nullableValue( new( storage ) T( _value ) ) {} Option( Option const& _other ) : nullableValue( _other ? new( storage ) T( *_other ) : CATCH_NULL ) {} ~Option() { reset(); } Option& operator= ( Option const& _other ) { if( &_other != this ) { reset(); if( _other ) nullableValue = new( storage ) T( *_other ); } return *this; } Option& operator = ( T const& _value ) { reset(); nullableValue = new( storage ) T( _value ); return *this; } void reset() { if( nullableValue ) nullableValue->~T(); nullableValue = CATCH_NULL; } T& operator*() { return *nullableValue; } T const& operator*() const { return *nullableValue; } T* operator->() { return nullableValue; } const T* operator->() const { return nullableValue; } T valueOr( T const& defaultValue ) const { return nullableValue ? *nullableValue : defaultValue; } bool some() const { return nullableValue != CATCH_NULL; } bool none() const { return nullableValue == CATCH_NULL; } bool operator !() const { return nullableValue == CATCH_NULL; } operator SafeBool::type() const { return SafeBool::makeSafe( some() ); } private: T *nullableValue; union { char storage[sizeof(T)]; // These are here to force alignment for the storage long double dummy1; void (*dummy2)(); long double dummy3; #ifdef CATCH_CONFIG_CPP11_LONG_LONG long long dummy4; #endif }; }; } // end namespace Catch #endif // TWOBLUECUBES_CATCH_OPTION_HPP_INCLUDED catch-1.12.1/include/internal/catch_platform.h000066400000000000000000000020021325474075300212600ustar00rootroot00000000000000/* * Created by Phil on 16/8/2013. * Copyright 2013 Two Blue Cubes Ltd. All rights reserved. * * Distributed under the Boost Software License, Version 1.0. (See accompanying * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) * */ #ifndef TWOBLUECUBES_CATCH_PLATFORM_H_INCLUDED #define TWOBLUECUBES_CATCH_PLATFORM_H_INCLUDED #if defined(__MAC_OS_X_VERSION_MIN_REQUIRED) # define CATCH_PLATFORM_MAC #elif defined(__IPHONE_OS_VERSION_MIN_REQUIRED) # define CATCH_PLATFORM_IPHONE #elif defined(linux) || defined(__linux) || defined(__linux__) # define CATCH_PLATFORM_LINUX #elif defined(WIN32) || defined(__WIN32__) || defined(_WIN32) || defined(_MSC_VER) # define CATCH_PLATFORM_WINDOWS # if !defined(NOMINMAX) && !defined(CATCH_CONFIG_NO_NOMINMAX) # define CATCH_DEFINES_NOMINMAX # endif # if !defined(WIN32_LEAN_AND_MEAN) && !defined(CATCH_CONFIG_NO_WIN32_LEAN_AND_MEAN) # define CATCH_DEFINES_WIN32_LEAN_AND_MEAN # endif #endif #endif // TWOBLUECUBES_CATCH_PLATFORM_H_INCLUDED catch-1.12.1/include/internal/catch_ptr.hpp000066400000000000000000000045401325474075300206120ustar00rootroot00000000000000/* * Created by Phil on 02/05/2012. * Copyright 2012 Two Blue Cubes Ltd. All rights reserved. * * Distributed under the Boost Software License, Version 1.0. (See accompanying * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) */ #ifndef TWOBLUECUBES_CATCH_PTR_HPP_INCLUDED #define TWOBLUECUBES_CATCH_PTR_HPP_INCLUDED #include "catch_common.h" #ifdef __clang__ #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wpadded" #endif namespace Catch { // An intrusive reference counting smart pointer. // T must implement addRef() and release() methods // typically implementing the IShared interface template class Ptr { public: Ptr() : m_p( CATCH_NULL ){} Ptr( T* p ) : m_p( p ){ if( m_p ) m_p->addRef(); } Ptr( Ptr const& other ) : m_p( other.m_p ){ if( m_p ) m_p->addRef(); } ~Ptr(){ if( m_p ) m_p->release(); } void reset() { if( m_p ) m_p->release(); m_p = CATCH_NULL; } Ptr& operator = ( T* p ){ Ptr temp( p ); swap( temp ); return *this; } Ptr& operator = ( Ptr const& other ){ Ptr temp( other ); swap( temp ); return *this; } void swap( Ptr& other ) { std::swap( m_p, other.m_p ); } T* get() const{ return m_p; } T& operator*() const { return *m_p; } T* operator->() const { return m_p; } bool operator !() const { return m_p == CATCH_NULL; } operator SafeBool::type() const { return SafeBool::makeSafe( m_p != CATCH_NULL ); } private: T* m_p; }; struct IShared : NonCopyable { virtual ~IShared(); virtual void addRef() const = 0; virtual void release() const = 0; }; template struct SharedImpl : T { SharedImpl() : m_rc( 0 ){} virtual void addRef() const { ++m_rc; } virtual void release() const { if( --m_rc == 0 ) delete this; } mutable unsigned int m_rc; }; } // end namespace Catch #ifdef __clang__ #pragma clang diagnostic pop #endif #endif // TWOBLUECUBES_CATCH_PTR_HPP_INCLUDED catch-1.12.1/include/internal/catch_reenable_warnings.h000066400000000000000000000011221325474075300231230ustar00rootroot00000000000000/* * Copyright 2014 Two Blue Cubes Ltd * * Distributed under the Boost Software License, Version 1.0. (See accompanying * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) */ #ifndef TWOBLUECUBES_CATCH_REENABLE_WARNINGS_H_INCLUDED #define TWOBLUECUBES_CATCH_REENABLE_WARNINGS_H_INCLUDED #ifdef __clang__ # ifdef __ICC // icpc defines the __clang__ macro # pragma warning(pop) # else # pragma clang diagnostic pop # endif #elif defined __GNUC__ # pragma GCC diagnostic pop #endif #endif // TWOBLUECUBES_CATCH_REENABLE_WARNINGS_H_INCLUDED catch-1.12.1/include/internal/catch_registry_hub.hpp000066400000000000000000000067271325474075300225240ustar00rootroot00000000000000/* * Created by Phil on 5/8/2012. * Copyright 2012 Two Blue Cubes Ltd. All rights reserved. * * Distributed under the Boost Software License, Version 1.0. (See accompanying * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) */ #ifndef TWOBLUECUBES_CATCH_REGISTRY_HUB_HPP_INCLUDED #define TWOBLUECUBES_CATCH_REGISTRY_HUB_HPP_INCLUDED #include "catch_interfaces_registry_hub.h" #include "catch_test_case_registry_impl.hpp" #include "catch_reporter_registry.hpp" #include "catch_exception_translator_registry.hpp" #include "catch_tag_alias_registry.h" namespace Catch { namespace { class RegistryHub : public IRegistryHub, public IMutableRegistryHub { RegistryHub( RegistryHub const& ); void operator=( RegistryHub const& ); public: // IRegistryHub RegistryHub() { } virtual IReporterRegistry const& getReporterRegistry() const CATCH_OVERRIDE { return m_reporterRegistry; } virtual ITestCaseRegistry const& getTestCaseRegistry() const CATCH_OVERRIDE { return m_testCaseRegistry; } virtual IExceptionTranslatorRegistry& getExceptionTranslatorRegistry() CATCH_OVERRIDE { return m_exceptionTranslatorRegistry; } virtual ITagAliasRegistry const& getTagAliasRegistry() const CATCH_OVERRIDE { return m_tagAliasRegistry; } public: // IMutableRegistryHub virtual void registerReporter( std::string const& name, Ptr const& factory ) CATCH_OVERRIDE { m_reporterRegistry.registerReporter( name, factory ); } virtual void registerListener( Ptr const& factory ) CATCH_OVERRIDE { m_reporterRegistry.registerListener( factory ); } virtual void registerTest( TestCase const& testInfo ) CATCH_OVERRIDE { m_testCaseRegistry.registerTest( testInfo ); } virtual void registerTranslator( const IExceptionTranslator* translator ) CATCH_OVERRIDE { m_exceptionTranslatorRegistry.registerTranslator( translator ); } virtual void registerTagAlias( std::string const& alias, std::string const& tag, SourceLineInfo const& lineInfo ) CATCH_OVERRIDE { m_tagAliasRegistry.add( alias, tag, lineInfo ); } private: TestRegistry m_testCaseRegistry; ReporterRegistry m_reporterRegistry; ExceptionTranslatorRegistry m_exceptionTranslatorRegistry; TagAliasRegistry m_tagAliasRegistry; }; // Single, global, instance inline RegistryHub*& getTheRegistryHub() { static RegistryHub* theRegistryHub = CATCH_NULL; if( !theRegistryHub ) theRegistryHub = new RegistryHub(); return theRegistryHub; } } IRegistryHub& getRegistryHub() { return *getTheRegistryHub(); } IMutableRegistryHub& getMutableRegistryHub() { return *getTheRegistryHub(); } void cleanUp() { delete getTheRegistryHub(); getTheRegistryHub() = CATCH_NULL; cleanUpContext(); } std::string translateActiveException() { return getRegistryHub().getExceptionTranslatorRegistry().translateActiveException(); } } // end namespace Catch #endif // TWOBLUECUBES_CATCH_REGISTRY_HUB_HPP_INCLUDED catch-1.12.1/include/internal/catch_reporter_registrars.hpp000066400000000000000000000075151325474075300241210ustar00rootroot00000000000000/* * Created by Phil on 31/12/2010. * Copyright 2010 Two Blue Cubes Ltd. All rights reserved. * * Distributed under the Boost Software License, Version 1.0. (See accompanying * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) */ #ifndef TWOBLUECUBES_CATCH_REPORTER_REGISTRARS_HPP_INCLUDED #define TWOBLUECUBES_CATCH_REPORTER_REGISTRARS_HPP_INCLUDED #include "catch_interfaces_registry_hub.h" #include "catch_legacy_reporter_adapter.h" namespace Catch { template class LegacyReporterRegistrar { class ReporterFactory : public IReporterFactory { virtual IStreamingReporter* create( ReporterConfig const& config ) const { return new LegacyReporterAdapter( new T( config ) ); } virtual std::string getDescription() const { return T::getDescription(); } }; public: LegacyReporterRegistrar( std::string const& name ) { getMutableRegistryHub().registerReporter( name, new ReporterFactory() ); } }; template class ReporterRegistrar { class ReporterFactory : public SharedImpl { // *** Please Note ***: // - If you end up here looking at a compiler error because it's trying to register // your custom reporter class be aware that the native reporter interface has changed // to IStreamingReporter. The "legacy" interface, IReporter, is still supported via // an adapter. Just use REGISTER_LEGACY_REPORTER to take advantage of the adapter. // However please consider updating to the new interface as the old one is now // deprecated and will probably be removed quite soon! // Please contact me via github if you have any questions at all about this. // In fact, ideally, please contact me anyway to let me know you've hit this - as I have // no idea who is actually using custom reporters at all (possibly no-one!). // The new interface is designed to minimise exposure to interface changes in the future. virtual IStreamingReporter* create( ReporterConfig const& config ) const { return new T( config ); } virtual std::string getDescription() const { return T::getDescription(); } }; public: ReporterRegistrar( std::string const& name ) { getMutableRegistryHub().registerReporter( name, new ReporterFactory() ); } }; template class ListenerRegistrar { class ListenerFactory : public SharedImpl { virtual IStreamingReporter* create( ReporterConfig const& config ) const { return new T( config ); } virtual std::string getDescription() const { return std::string(); } }; public: ListenerRegistrar() { getMutableRegistryHub().registerListener( new ListenerFactory() ); } }; } #define INTERNAL_CATCH_REGISTER_LEGACY_REPORTER( name, reporterType ) \ namespace{ Catch::LegacyReporterRegistrar catch_internal_RegistrarFor##reporterType( name ); } #define INTERNAL_CATCH_REGISTER_REPORTER( name, reporterType ) \ namespace{ Catch::ReporterRegistrar catch_internal_RegistrarFor##reporterType( name ); } // Deprecated - use the form without INTERNAL_ #define INTERNAL_CATCH_REGISTER_LISTENER( listenerType ) \ namespace{ Catch::ListenerRegistrar catch_internal_RegistrarFor##listenerType; } #define CATCH_REGISTER_LISTENER( listenerType ) \ namespace{ Catch::ListenerRegistrar catch_internal_RegistrarFor##listenerType; } #endif // TWOBLUECUBES_CATCH_REPORTER_REGISTRARS_HPP_INCLUDED catch-1.12.1/include/internal/catch_reporter_registry.hpp000066400000000000000000000031071325474075300235750ustar00rootroot00000000000000/* * Created by Phil on 29/10/2010. * Copyright 2010 Two Blue Cubes Ltd. All rights reserved. * * Distributed under the Boost Software License, Version 1.0. (See accompanying * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) */ #ifndef TWOBLUECUBES_CATCH_REPORTER_REGISTRY_HPP_INCLUDED #define TWOBLUECUBES_CATCH_REPORTER_REGISTRY_HPP_INCLUDED #include "catch_interfaces_reporter.h" #include namespace Catch { class ReporterRegistry : public IReporterRegistry { public: virtual ~ReporterRegistry() CATCH_OVERRIDE {} virtual IStreamingReporter* create( std::string const& name, Ptr const& config ) const CATCH_OVERRIDE { FactoryMap::const_iterator it = m_factories.find( name ); if( it == m_factories.end() ) return CATCH_NULL; return it->second->create( ReporterConfig( config ) ); } void registerReporter( std::string const& name, Ptr const& factory ) { m_factories.insert( std::make_pair( name, factory ) ); } void registerListener( Ptr const& factory ) { m_listeners.push_back( factory ); } virtual FactoryMap const& getFactories() const CATCH_OVERRIDE { return m_factories; } virtual Listeners const& getListeners() const CATCH_OVERRIDE { return m_listeners; } private: FactoryMap m_factories; Listeners m_listeners; }; } #endif // TWOBLUECUBES_CATCH_REPORTER_REGISTRY_HPP_INCLUDED catch-1.12.1/include/internal/catch_result_builder.h000066400000000000000000000102021325474075300224610ustar00rootroot00000000000000/* * Created by Phil on 28/5/2014. * Copyright 2014 Two Blue Cubes Ltd. All rights reserved. * * Distributed under the Boost Software License, Version 1.0. (See accompanying * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) */ #ifndef TWOBLUECUBES_CATCH_RESULT_BUILDER_H_INCLUDED #define TWOBLUECUBES_CATCH_RESULT_BUILDER_H_INCLUDED #include "catch_result_type.h" #include "catch_assertionresult.h" #include "catch_common.h" #include "catch_matchers.hpp" namespace Catch { struct TestFailureException{}; template class ExpressionLhs; struct CopyableStream { CopyableStream() {} CopyableStream( CopyableStream const& other ) { oss << other.oss.str(); } CopyableStream& operator=( CopyableStream const& other ) { oss.str(std::string()); oss << other.oss.str(); return *this; } std::ostringstream oss; }; class ResultBuilder : public DecomposedExpression { public: ResultBuilder( char const* macroName, SourceLineInfo const& lineInfo, char const* capturedExpression, ResultDisposition::Flags resultDisposition, char const* secondArg = "" ); ~ResultBuilder(); template ExpressionLhs operator <= ( T const& operand ); ExpressionLhs operator <= ( bool value ); template ResultBuilder& operator << ( T const& value ) { stream().oss << value; return *this; } ResultBuilder& setResultType( ResultWas::OfType result ); ResultBuilder& setResultType( bool result ); void endExpression( DecomposedExpression const& expr ); virtual void reconstructExpression( std::string& dest ) const CATCH_OVERRIDE; AssertionResult build() const; AssertionResult build( DecomposedExpression const& expr ) const; void useActiveException( ResultDisposition::Flags resultDisposition = ResultDisposition::Normal ); void captureResult( ResultWas::OfType resultType ); void captureExpression(); void captureExpectedException( std::string const& expectedMessage ); void captureExpectedException( Matchers::Impl::MatcherBase const& matcher ); void handleResult( AssertionResult const& result ); void react(); bool shouldDebugBreak() const; bool allowThrows() const; template void captureMatch( ArgT const& arg, MatcherT const& matcher, char const* matcherString ); void setExceptionGuard(); void unsetExceptionGuard(); private: AssertionInfo m_assertionInfo; AssertionResultData m_data; CopyableStream &stream() { if(!m_usedStream) { m_usedStream = true; m_stream().oss.str(""); } return m_stream(); } static CopyableStream &m_stream() { static CopyableStream s; return s; } bool m_shouldDebugBreak; bool m_shouldThrow; bool m_guardException; bool m_usedStream; }; } // namespace Catch // Include after due to circular dependency: #include "catch_expression_lhs.hpp" namespace Catch { template ExpressionLhs ResultBuilder::operator <= ( T const& operand ) { return ExpressionLhs( *this, operand ); } inline ExpressionLhs ResultBuilder::operator <= ( bool value ) { return ExpressionLhs( *this, value ); } template void ResultBuilder::captureMatch( ArgT const& arg, MatcherT const& matcher, char const* matcherString ) { MatchExpression expr( arg, matcher, matcherString ); setResultType( matcher.match( arg ) ); endExpression( expr ); } } // namespace Catch #endif // TWOBLUECUBES_CATCH_RESULT_BUILDER_H_INCLUDED catch-1.12.1/include/internal/catch_result_builder.hpp000066400000000000000000000150571325474075300230360ustar00rootroot00000000000000/* * Created by Phil on 28/5/2014. * Copyright 2014 Two Blue Cubes Ltd. All rights reserved. * * Distributed under the Boost Software License, Version 1.0. (See accompanying * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) */ #ifndef TWOBLUECUBES_CATCH_RESULT_BUILDER_HPP_INCLUDED #define TWOBLUECUBES_CATCH_RESULT_BUILDER_HPP_INCLUDED #include "catch_result_builder.h" #include "catch_context.h" #include "catch_interfaces_config.h" #include "catch_interfaces_runner.h" #include "catch_interfaces_capture.h" #include "catch_interfaces_registry_hub.h" #include "catch_wildcard_pattern.hpp" namespace Catch { ResultBuilder::ResultBuilder( char const* macroName, SourceLineInfo const& lineInfo, char const* capturedExpression, ResultDisposition::Flags resultDisposition, char const* secondArg ) : m_assertionInfo( macroName, lineInfo, capturedExpression, resultDisposition, secondArg ), m_shouldDebugBreak( false ), m_shouldThrow( false ), m_guardException( false ), m_usedStream( false ) {} ResultBuilder::~ResultBuilder() { #if defined(CATCH_CONFIG_FAST_COMPILE) if ( m_guardException ) { stream().oss << "Exception translation was disabled by CATCH_CONFIG_FAST_COMPILE"; captureResult( ResultWas::ThrewException ); getCurrentContext().getResultCapture()->exceptionEarlyReported(); } #endif } ResultBuilder& ResultBuilder::setResultType( ResultWas::OfType result ) { m_data.resultType = result; return *this; } ResultBuilder& ResultBuilder::setResultType( bool result ) { m_data.resultType = result ? ResultWas::Ok : ResultWas::ExpressionFailed; return *this; } void ResultBuilder::endExpression( DecomposedExpression const& expr ) { // Flip bool results if FalseTest flag is set if( isFalseTest( m_assertionInfo.resultDisposition ) ) { m_data.negate( expr.isBinaryExpression() ); } getResultCapture().assertionRun(); if(getCurrentContext().getConfig()->includeSuccessfulResults() || m_data.resultType != ResultWas::Ok) { AssertionResult result = build( expr ); handleResult( result ); } else getResultCapture().assertionPassed(); } void ResultBuilder::useActiveException( ResultDisposition::Flags resultDisposition ) { m_assertionInfo.resultDisposition = resultDisposition; stream().oss << Catch::translateActiveException(); captureResult( ResultWas::ThrewException ); } void ResultBuilder::captureResult( ResultWas::OfType resultType ) { setResultType( resultType ); captureExpression(); } void ResultBuilder::captureExpectedException( std::string const& expectedMessage ) { if( expectedMessage.empty() ) captureExpectedException( Matchers::Impl::MatchAllOf() ); else captureExpectedException( Matchers::Equals( expectedMessage ) ); } void ResultBuilder::captureExpectedException( Matchers::Impl::MatcherBase const& matcher ) { assert( !isFalseTest( m_assertionInfo.resultDisposition ) ); AssertionResultData data = m_data; data.resultType = ResultWas::Ok; data.reconstructedExpression = capturedExpressionWithSecondArgument(m_assertionInfo.capturedExpression, m_assertionInfo.secondArg); std::string actualMessage = Catch::translateActiveException(); if( !matcher.match( actualMessage ) ) { data.resultType = ResultWas::ExpressionFailed; data.reconstructedExpression = actualMessage; } AssertionResult result( m_assertionInfo, data ); handleResult( result ); } void ResultBuilder::captureExpression() { AssertionResult result = build(); handleResult( result ); } void ResultBuilder::handleResult( AssertionResult const& result ) { getResultCapture().assertionEnded( result ); if( !result.isOk() ) { if( getCurrentContext().getConfig()->shouldDebugBreak() ) m_shouldDebugBreak = true; if( getCurrentContext().getRunner()->aborting() || (m_assertionInfo.resultDisposition & ResultDisposition::Normal) ) m_shouldThrow = true; } } void ResultBuilder::react() { #if defined(CATCH_CONFIG_FAST_COMPILE) if (m_shouldDebugBreak) { /////////////////////////////////////////////////////////////////// // To inspect the state during test, you need to go one level up the callstack // To go back to the test and change execution, jump over the throw statement /////////////////////////////////////////////////////////////////// CATCH_BREAK_INTO_DEBUGGER(); } #endif if( m_shouldThrow ) throw Catch::TestFailureException(); } bool ResultBuilder::shouldDebugBreak() const { return m_shouldDebugBreak; } bool ResultBuilder::allowThrows() const { return getCurrentContext().getConfig()->allowThrows(); } AssertionResult ResultBuilder::build() const { return build( *this ); } // CAVEAT: The returned AssertionResult stores a pointer to the argument expr, // a temporary DecomposedExpression, which in turn holds references to // operands, possibly temporary as well. // It should immediately be passed to handleResult; if the expression // needs to be reported, its string expansion must be composed before // the temporaries are destroyed. AssertionResult ResultBuilder::build( DecomposedExpression const& expr ) const { assert( m_data.resultType != ResultWas::Unknown ); AssertionResultData data = m_data; if(m_usedStream) data.message = m_stream().oss.str(); data.decomposedExpression = &expr; // for lazy reconstruction return AssertionResult( m_assertionInfo, data ); } void ResultBuilder::reconstructExpression( std::string& dest ) const { dest = capturedExpressionWithSecondArgument(m_assertionInfo.capturedExpression, m_assertionInfo.secondArg); } void ResultBuilder::setExceptionGuard() { m_guardException = true; } void ResultBuilder::unsetExceptionGuard() { m_guardException = false; } } // end namespace Catch #endif // TWOBLUECUBES_CATCH_RESULT_BUILDER_HPP_INCLUDED catch-1.12.1/include/internal/catch_result_type.h000066400000000000000000000037761325474075300220360ustar00rootroot00000000000000/* * Created by Phil on 07/01/2011. * Copyright 2011 Two Blue Cubes Ltd. All rights reserved. * * Distributed under the Boost Software License, Version 1.0. (See accompanying * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) */ #ifndef TWOBLUECUBES_CATCH_RESULT_TYPE_H_INCLUDED #define TWOBLUECUBES_CATCH_RESULT_TYPE_H_INCLUDED namespace Catch { // ResultWas::OfType enum struct ResultWas { enum OfType { Unknown = -1, Ok = 0, Info = 1, Warning = 2, FailureBit = 0x10, ExpressionFailed = FailureBit | 1, ExplicitFailure = FailureBit | 2, Exception = 0x100 | FailureBit, ThrewException = Exception | 1, DidntThrowException = Exception | 2, FatalErrorCondition = 0x200 | FailureBit }; }; inline bool isOk( ResultWas::OfType resultType ) { return ( resultType & ResultWas::FailureBit ) == 0; } inline bool isJustInfo( int flags ) { return flags == ResultWas::Info; } // ResultDisposition::Flags enum struct ResultDisposition { enum Flags { Normal = 0x01, ContinueOnFailure = 0x02, // Failures fail test, but execution continues FalseTest = 0x04, // Prefix expression with ! SuppressFail = 0x08 // Failures are reported but do not fail the test }; }; inline ResultDisposition::Flags operator | ( ResultDisposition::Flags lhs, ResultDisposition::Flags rhs ) { return static_cast( static_cast( lhs ) | static_cast( rhs ) ); } inline bool shouldContinueOnFailure( int flags ) { return ( flags & ResultDisposition::ContinueOnFailure ) != 0; } inline bool isFalseTest( int flags ) { return ( flags & ResultDisposition::FalseTest ) != 0; } inline bool shouldSuppressFailure( int flags ) { return ( flags & ResultDisposition::SuppressFail ) != 0; } } // end namespace Catch #endif // TWOBLUECUBES_CATCH_RESULT_TYPE_H_INCLUDED catch-1.12.1/include/internal/catch_run_context.hpp000066400000000000000000000374041325474075300223620ustar00rootroot00000000000000 /* * Created by Phil on 22/10/2010. * Copyright 2010 Two Blue Cubes Ltd. All rights reserved. * * Distributed under the Boost Software License, Version 1.0. (See accompanying * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) */ #ifndef TWOBLUECUBES_CATCH_RUNNER_IMPL_HPP_INCLUDED #define TWOBLUECUBES_CATCH_RUNNER_IMPL_HPP_INCLUDED #include "catch_interfaces_runner.h" #include "catch_interfaces_reporter.h" #include "catch_interfaces_exception.h" #include "catch_config.hpp" #include "catch_test_registry.hpp" #include "catch_test_case_info.h" #include "catch_capture.hpp" #include "catch_totals.hpp" #include "catch_test_spec.hpp" #include "catch_test_case_tracker.hpp" #include "catch_timer.h" #include "catch_result_builder.h" #include "catch_fatal_condition.hpp" #include #include namespace Catch { class StreamRedirect { public: StreamRedirect( std::ostream& stream, std::string& targetString ) : m_stream( stream ), m_prevBuf( stream.rdbuf() ), m_targetString( targetString ) { stream.rdbuf( m_oss.rdbuf() ); } ~StreamRedirect() { m_targetString += m_oss.str(); m_stream.rdbuf( m_prevBuf ); } private: std::ostream& m_stream; std::streambuf* m_prevBuf; std::ostringstream m_oss; std::string& m_targetString; }; // StdErr has two constituent streams in C++, std::cerr and std::clog // This means that we need to redirect 2 streams into 1 to keep proper // order of writes and cannot use StreamRedirect on its own class StdErrRedirect { public: StdErrRedirect(std::string& targetString) :m_cerrBuf( cerr().rdbuf() ), m_clogBuf(clog().rdbuf()), m_targetString(targetString){ cerr().rdbuf(m_oss.rdbuf()); clog().rdbuf(m_oss.rdbuf()); } ~StdErrRedirect() { m_targetString += m_oss.str(); cerr().rdbuf(m_cerrBuf); clog().rdbuf(m_clogBuf); } private: std::streambuf* m_cerrBuf; std::streambuf* m_clogBuf; std::ostringstream m_oss; std::string& m_targetString; }; /////////////////////////////////////////////////////////////////////////// class RunContext : public IResultCapture, public IRunner { RunContext( RunContext const& ); void operator =( RunContext const& ); public: explicit RunContext( Ptr const& _config, Ptr const& reporter ) : m_runInfo( _config->name() ), m_context( getCurrentMutableContext() ), m_activeTestCase( CATCH_NULL ), m_config( _config ), m_reporter( reporter ), m_shouldReportUnexpected ( true ) { m_context.setRunner( this ); m_context.setConfig( m_config ); m_context.setResultCapture( this ); m_reporter->testRunStarting( m_runInfo ); } virtual ~RunContext() { m_reporter->testRunEnded( TestRunStats( m_runInfo, m_totals, aborting() ) ); } void testGroupStarting( std::string const& testSpec, std::size_t groupIndex, std::size_t groupsCount ) { m_reporter->testGroupStarting( GroupInfo( testSpec, groupIndex, groupsCount ) ); } void testGroupEnded( std::string const& testSpec, Totals const& totals, std::size_t groupIndex, std::size_t groupsCount ) { m_reporter->testGroupEnded( TestGroupStats( GroupInfo( testSpec, groupIndex, groupsCount ), totals, aborting() ) ); } Totals runTest( TestCase const& testCase ) { Totals prevTotals = m_totals; std::string redirectedCout; std::string redirectedCerr; TestCaseInfo testInfo = testCase.getTestCaseInfo(); m_reporter->testCaseStarting( testInfo ); m_activeTestCase = &testCase; do { ITracker& rootTracker = m_trackerContext.startRun(); assert( rootTracker.isSectionTracker() ); static_cast( rootTracker ).addInitialFilters( m_config->getSectionsToRun() ); do { m_trackerContext.startCycle(); m_testCaseTracker = &SectionTracker::acquire( m_trackerContext, TestCaseTracking::NameAndLocation( testInfo.name, testInfo.lineInfo ) ); runCurrentTest( redirectedCout, redirectedCerr ); } while( !m_testCaseTracker->isSuccessfullyCompleted() && !aborting() ); } // !TBD: deprecated - this will be replaced by indexed trackers while( getCurrentContext().advanceGeneratorsForCurrentTest() && !aborting() ); Totals deltaTotals = m_totals.delta( prevTotals ); if( testInfo.expectedToFail() && deltaTotals.testCases.passed > 0 ) { deltaTotals.assertions.failed++; deltaTotals.testCases.passed--; deltaTotals.testCases.failed++; } m_totals.testCases += deltaTotals.testCases; m_reporter->testCaseEnded( TestCaseStats( testInfo, deltaTotals, redirectedCout, redirectedCerr, aborting() ) ); m_activeTestCase = CATCH_NULL; m_testCaseTracker = CATCH_NULL; return deltaTotals; } Ptr config() const { return m_config; } private: // IResultCapture virtual void assertionEnded( AssertionResult const& result ) { if( result.getResultType() == ResultWas::Ok ) { m_totals.assertions.passed++; } else if( !result.isOk() ) { if( m_activeTestCase->getTestCaseInfo().okToFail() ) m_totals.assertions.failedButOk++; else m_totals.assertions.failed++; } // We have no use for the return value (whether messages should be cleared), because messages were made scoped // and should be let to clear themselves out. static_cast(m_reporter->assertionEnded(AssertionStats(result, m_messages, m_totals))); // Reset working state m_lastAssertionInfo = AssertionInfo( "", m_lastAssertionInfo.lineInfo, "{Unknown expression after the reported line}" , m_lastAssertionInfo.resultDisposition ); m_lastResult = result; } virtual bool lastAssertionPassed() { return m_totals.assertions.passed == (m_prevPassed + 1); } virtual void assertionPassed() { m_totals.assertions.passed++; m_lastAssertionInfo.capturedExpression = "{Unknown expression after the reported line}"; m_lastAssertionInfo.macroName = ""; } virtual void assertionRun() { m_prevPassed = m_totals.assertions.passed; } virtual bool sectionStarted ( SectionInfo const& sectionInfo, Counts& assertions ) { ITracker& sectionTracker = SectionTracker::acquire( m_trackerContext, TestCaseTracking::NameAndLocation( sectionInfo.name, sectionInfo.lineInfo ) ); if( !sectionTracker.isOpen() ) return false; m_activeSections.push_back( §ionTracker ); m_lastAssertionInfo.lineInfo = sectionInfo.lineInfo; m_reporter->sectionStarting( sectionInfo ); assertions = m_totals.assertions; return true; } bool testForMissingAssertions( Counts& assertions ) { if( assertions.total() != 0 ) return false; if( !m_config->warnAboutMissingAssertions() ) return false; if( m_trackerContext.currentTracker().hasChildren() ) return false; m_totals.assertions.failed++; assertions.failed++; return true; } virtual void sectionEnded( SectionEndInfo const& endInfo ) { Counts assertions = m_totals.assertions - endInfo.prevAssertions; bool missingAssertions = testForMissingAssertions( assertions ); if( !m_activeSections.empty() ) { m_activeSections.back()->close(); m_activeSections.pop_back(); } m_reporter->sectionEnded( SectionStats( endInfo.sectionInfo, assertions, endInfo.durationInSeconds, missingAssertions ) ); m_messages.clear(); } virtual void sectionEndedEarly( SectionEndInfo const& endInfo ) { if( m_unfinishedSections.empty() ) m_activeSections.back()->fail(); else m_activeSections.back()->close(); m_activeSections.pop_back(); m_unfinishedSections.push_back( endInfo ); } virtual void pushScopedMessage( MessageInfo const& message ) { m_messages.push_back( message ); } virtual void popScopedMessage( MessageInfo const& message ) { m_messages.erase( std::remove( m_messages.begin(), m_messages.end(), message ), m_messages.end() ); } virtual std::string getCurrentTestName() const { return m_activeTestCase ? m_activeTestCase->getTestCaseInfo().name : std::string(); } virtual const AssertionResult* getLastResult() const { return &m_lastResult; } virtual void exceptionEarlyReported() { m_shouldReportUnexpected = false; } virtual void handleFatalErrorCondition( std::string const& message ) { // Don't rebuild the result -- the stringification itself can cause more fatal errors // Instead, fake a result data. AssertionResultData tempResult; tempResult.resultType = ResultWas::FatalErrorCondition; tempResult.message = message; AssertionResult result(m_lastAssertionInfo, tempResult); getResultCapture().assertionEnded(result); handleUnfinishedSections(); // Recreate section for test case (as we will lose the one that was in scope) TestCaseInfo const& testCaseInfo = m_activeTestCase->getTestCaseInfo(); SectionInfo testCaseSection( testCaseInfo.lineInfo, testCaseInfo.name, testCaseInfo.description ); Counts assertions; assertions.failed = 1; SectionStats testCaseSectionStats( testCaseSection, assertions, 0, false ); m_reporter->sectionEnded( testCaseSectionStats ); TestCaseInfo testInfo = m_activeTestCase->getTestCaseInfo(); Totals deltaTotals; deltaTotals.testCases.failed = 1; deltaTotals.assertions.failed = 1; m_reporter->testCaseEnded( TestCaseStats( testInfo, deltaTotals, std::string(), std::string(), false ) ); m_totals.testCases.failed++; testGroupEnded( std::string(), m_totals, 1, 1 ); m_reporter->testRunEnded( TestRunStats( m_runInfo, m_totals, false ) ); } public: // !TBD We need to do this another way! bool aborting() const { return m_totals.assertions.failed == static_cast( m_config->abortAfter() ); } private: void runCurrentTest( std::string& redirectedCout, std::string& redirectedCerr ) { TestCaseInfo const& testCaseInfo = m_activeTestCase->getTestCaseInfo(); SectionInfo testCaseSection( testCaseInfo.lineInfo, testCaseInfo.name, testCaseInfo.description ); m_reporter->sectionStarting( testCaseSection ); Counts prevAssertions = m_totals.assertions; double duration = 0; m_shouldReportUnexpected = true; try { m_lastAssertionInfo = AssertionInfo( "TEST_CASE", testCaseInfo.lineInfo, "", ResultDisposition::Normal ); seedRng( *m_config ); Timer timer; timer.start(); if( m_reporter->getPreferences().shouldRedirectStdOut ) { StreamRedirect coutRedir( Catch::cout(), redirectedCout ); StdErrRedirect errRedir( redirectedCerr ); invokeActiveTestCase(); } else { invokeActiveTestCase(); } duration = timer.getElapsedSeconds(); } catch( TestFailureException& ) { // This just means the test was aborted due to failure } catch(...) { // Under CATCH_CONFIG_FAST_COMPILE, unexpected exceptions under REQUIRE assertions // are reported without translation at the point of origin. if (m_shouldReportUnexpected) { makeUnexpectedResultBuilder().useActiveException(); } } m_testCaseTracker->close(); handleUnfinishedSections(); m_messages.clear(); Counts assertions = m_totals.assertions - prevAssertions; bool missingAssertions = testForMissingAssertions( assertions ); SectionStats testCaseSectionStats( testCaseSection, assertions, duration, missingAssertions ); m_reporter->sectionEnded( testCaseSectionStats ); } void invokeActiveTestCase() { FatalConditionHandler fatalConditionHandler; // Handle signals m_activeTestCase->invoke(); fatalConditionHandler.reset(); } private: ResultBuilder makeUnexpectedResultBuilder() const { return ResultBuilder( m_lastAssertionInfo.macroName, m_lastAssertionInfo.lineInfo, m_lastAssertionInfo.capturedExpression, m_lastAssertionInfo.resultDisposition ); } void handleUnfinishedSections() { // If sections ended prematurely due to an exception we stored their // infos here so we can tear them down outside the unwind process. for( std::vector::const_reverse_iterator it = m_unfinishedSections.rbegin(), itEnd = m_unfinishedSections.rend(); it != itEnd; ++it ) sectionEnded( *it ); m_unfinishedSections.clear(); } TestRunInfo m_runInfo; IMutableContext& m_context; TestCase const* m_activeTestCase; ITracker* m_testCaseTracker; ITracker* m_currentSectionTracker; AssertionResult m_lastResult; Ptr m_config; Totals m_totals; Ptr m_reporter; std::vector m_messages; AssertionInfo m_lastAssertionInfo; std::vector m_unfinishedSections; std::vector m_activeSections; TrackerContext m_trackerContext; size_t m_prevPassed; bool m_shouldReportUnexpected; }; IResultCapture& getResultCapture() { if( IResultCapture* capture = getCurrentContext().getResultCapture() ) return *capture; else throw std::logic_error( "No result capture instance" ); } } // end namespace Catch #endif // TWOBLUECUBES_CATCH_RUNNER_IMPL_HPP_INCLUDED catch-1.12.1/include/internal/catch_section.h000066400000000000000000000025341325474075300211120ustar00rootroot00000000000000/* * Created by Phil on 03/12/2013. * Copyright 2013 Two Blue Cubes Ltd. All rights reserved. * * Distributed under the Boost Software License, Version 1.0. (See accompanying * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) */ #ifndef TWOBLUECUBES_CATCH_SECTION_H_INCLUDED #define TWOBLUECUBES_CATCH_SECTION_H_INCLUDED #include "catch_section_info.h" #include "catch_totals.hpp" #include "catch_timer.h" #include namespace Catch { class Section : NonCopyable { public: Section( SectionInfo const& info ); ~Section(); // This indicates whether the section should be executed or not operator bool() const; private: SectionInfo m_info; std::string m_name; Counts m_assertions; bool m_sectionIncluded; Timer m_timer; }; } // end namespace Catch #ifdef CATCH_CONFIG_VARIADIC_MACROS #define INTERNAL_CATCH_SECTION( ... ) \ if( Catch::Section const& INTERNAL_CATCH_UNIQUE_NAME( catch_internal_Section ) = Catch::SectionInfo( CATCH_INTERNAL_LINEINFO, __VA_ARGS__ ) ) #else #define INTERNAL_CATCH_SECTION( name, desc ) \ if( Catch::Section const& INTERNAL_CATCH_UNIQUE_NAME( catch_internal_Section ) = Catch::SectionInfo( CATCH_INTERNAL_LINEINFO, name, desc ) ) #endif #endif // TWOBLUECUBES_CATCH_SECTION_H_INCLUDED catch-1.12.1/include/internal/catch_section.hpp000066400000000000000000000032231325474075300214460ustar00rootroot00000000000000/* * Created by Phil on 03/11/2010. * Copyright 2010 Two Blue Cubes Ltd. All rights reserved. * * Distributed under the Boost Software License, Version 1.0. (See accompanying * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) */ #ifndef TWOBLUECUBES_CATCH_SECTION_HPP_INCLUDED #define TWOBLUECUBES_CATCH_SECTION_HPP_INCLUDED #include "catch_section.h" #include "catch_capture.hpp" #include "catch_compiler_capabilities.h" namespace Catch { SectionInfo::SectionInfo ( SourceLineInfo const& _lineInfo, std::string const& _name, std::string const& _description ) : name( _name ), description( _description ), lineInfo( _lineInfo ) {} Section::Section( SectionInfo const& info ) : m_info( info ), m_sectionIncluded( getResultCapture().sectionStarted( m_info, m_assertions ) ) { m_timer.start(); } #if defined(_MSC_VER) #pragma warning(push) #pragma warning(disable:4996) // std::uncaught_exception is deprecated in C++17 #endif Section::~Section() { if( m_sectionIncluded ) { SectionEndInfo endInfo( m_info, m_assertions, m_timer.getElapsedSeconds() ); if( std::uncaught_exception() ) getResultCapture().sectionEndedEarly( endInfo ); else getResultCapture().sectionEnded( endInfo ); } } #if defined(_MSC_VER) #pragma warning(pop) #endif // This indicates whether the section should be executed or not Section::operator bool() const { return m_sectionIncluded; } } // end namespace Catch #endif // TWOBLUECUBES_CATCH_SECTION_HPP_INCLUDED catch-1.12.1/include/internal/catch_section_info.h000066400000000000000000000022771325474075300221310ustar00rootroot00000000000000/* * Created by Phil on 03/11/2010. * Copyright 2010 Two Blue Cubes Ltd. All rights reserved. * * Distributed under the Boost Software License, Version 1.0. (See accompanying * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) */ #ifndef TWOBLUECUBES_CATCH_SECTION_INFO_H_INCLUDED #define TWOBLUECUBES_CATCH_SECTION_INFO_H_INCLUDED #include "catch_common.h" #include "catch_totals.hpp" #include namespace Catch { struct SectionInfo { SectionInfo ( SourceLineInfo const& _lineInfo, std::string const& _name, std::string const& _description = std::string() ); std::string name; std::string description; SourceLineInfo lineInfo; }; struct SectionEndInfo { SectionEndInfo( SectionInfo const& _sectionInfo, Counts const& _prevAssertions, double _durationInSeconds ) : sectionInfo( _sectionInfo ), prevAssertions( _prevAssertions ), durationInSeconds( _durationInSeconds ) {} SectionInfo sectionInfo; Counts prevAssertions; double durationInSeconds; }; } // end namespace Catch #endif // TWOBLUECUBES_CATCH_SECTION_INFO_H_INCLUDED catch-1.12.1/include/internal/catch_section_info.hpp000066400000000000000000000055661325474075300224750ustar00rootroot00000000000000/* * Created by Phil Nash on 4/5/2012 * Copyright 2012 Two Blue Cubes Ltd. All rights reserved. * * Distributed under the Boost Software License, Version 1.0. (See accompanying * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) */ #ifndef TWOBLUECUBES_CATCH_SECTION_INFO_HPP_INCLUDED #define TWOBLUECUBES_CATCH_SECTION_INFO_HPP_INCLUDED #include "catch_section_info.h" namespace Catch { class RunningSection { public: typedef std::vector SubSections; enum State { Root, Unknown, Branch, TestedBranch, TestedLeaf }; RunningSection( RunningSection* parent, std::string const& name ) : m_state( Unknown ), m_parent( parent ), m_name( name ) {} RunningSection( std::string const& name ) : m_state( Root ), m_parent( CATCH_NULL ), m_name( name ) {} ~RunningSection() { deleteAll( m_subSections ); } std::string getName() const { return m_name; } bool shouldRun() const { return m_state < TestedBranch; } bool isBranch() const { return m_state == Branch; } const RunningSection* getParent() const { return m_parent; } bool hasUntestedSections() const { if( m_state == Unknown ) return true; for( SubSections::const_iterator it = m_subSections.begin(); it != m_subSections.end(); ++it) if( (*it)->hasUntestedSections() ) return true; return false; } // Mutable methods: RunningSection* getParent() { return m_parent; } RunningSection* findOrAddSubSection( std::string const& name, bool& changed ) { for( SubSections::const_iterator it = m_subSections.begin(); it != m_subSections.end(); ++it) if( (*it)->getName() == name ) return *it; RunningSection* subSection = new RunningSection( this, name ); m_subSections.push_back( subSection ); m_state = Branch; changed = true; return subSection; } bool ran() { if( m_state >= Branch ) return false; m_state = TestedLeaf; return true; } void ranToCompletion() { if( m_state == Branch && !hasUntestedSections() ) m_state = TestedBranch; } private: State m_state; RunningSection* m_parent; std::string m_name; SubSections m_subSections; }; } #endif // TWOBLUECUBES_CATCH_SECTION_INFO_HPP_INCLUDED catch-1.12.1/include/internal/catch_stream.h000066400000000000000000000031151325474075300207350ustar00rootroot00000000000000/* * Created by Phil on 2/12/2013. * Copyright 2013 Two Blue Cubes Ltd. All rights reserved. * * Distributed under the Boost Software License, Version 1.0. (See accompanying * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) * */ #ifndef TWOBLUECUBES_CATCH_STREAM_H_INCLUDED #define TWOBLUECUBES_CATCH_STREAM_H_INCLUDED #include "catch_compiler_capabilities.h" #include "catch_streambuf.h" #include #include #include #include namespace Catch { std::ostream& cout(); std::ostream& cerr(); std::ostream& clog(); struct IStream { virtual ~IStream() CATCH_NOEXCEPT; virtual std::ostream& stream() const = 0; }; class FileStream : public IStream { mutable std::ofstream m_ofs; public: FileStream( std::string const& filename ); virtual ~FileStream() CATCH_NOEXCEPT; public: // IStream virtual std::ostream& stream() const CATCH_OVERRIDE; }; class CoutStream : public IStream { mutable std::ostream m_os; public: CoutStream(); virtual ~CoutStream() CATCH_NOEXCEPT; public: // IStream virtual std::ostream& stream() const CATCH_OVERRIDE; }; class DebugOutStream : public IStream { CATCH_AUTO_PTR( StreamBufBase ) m_streamBuf; mutable std::ostream m_os; public: DebugOutStream(); virtual ~DebugOutStream() CATCH_NOEXCEPT; public: // IStream virtual std::ostream& stream() const CATCH_OVERRIDE; }; } #endif // TWOBLUECUBES_CATCH_STREAM_H_INCLUDED catch-1.12.1/include/internal/catch_stream.hpp000066400000000000000000000053741325474075300213060ustar00rootroot00000000000000/* * Created by Phil on 17/01/2011. * Copyright 2011 Two Blue Cubes Ltd. All rights reserved. * * Distributed under the Boost Software License, Version 1.0. (See accompanying * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) * */ #ifndef TWOBLUECUBES_CATCH_STREAM_HPP_INCLUDED #define TWOBLUECUBES_CATCH_STREAM_HPP_INCLUDED #include "catch_stream.h" #include "catch_debugger.h" #include #include #include namespace Catch { template class StreamBufImpl : public StreamBufBase { char data[bufferSize]; WriterF m_writer; public: StreamBufImpl() { setp( data, data + sizeof(data) ); } ~StreamBufImpl() CATCH_NOEXCEPT { sync(); } private: int overflow( int c ) { sync(); if( c != EOF ) { if( pbase() == epptr() ) m_writer( std::string( 1, static_cast( c ) ) ); else sputc( static_cast( c ) ); } return 0; } int sync() { if( pbase() != pptr() ) { m_writer( std::string( pbase(), static_cast( pptr() - pbase() ) ) ); setp( pbase(), epptr() ); } return 0; } }; /////////////////////////////////////////////////////////////////////////// FileStream::FileStream( std::string const& filename ) { m_ofs.open( filename.c_str() ); if( m_ofs.fail() ) { std::ostringstream oss; oss << "Unable to open file: '" << filename << '\''; throw std::domain_error( oss.str() ); } } std::ostream& FileStream::stream() const { return m_ofs; } struct OutputDebugWriter { void operator()( std::string const&str ) { writeToDebugConsole( str ); } }; DebugOutStream::DebugOutStream() : m_streamBuf( new StreamBufImpl() ), m_os( m_streamBuf.get() ) {} std::ostream& DebugOutStream::stream() const { return m_os; } // Store the streambuf from cout up-front because // cout may get redirected when running tests CoutStream::CoutStream() : m_os( Catch::cout().rdbuf() ) {} std::ostream& CoutStream::stream() const { return m_os; } #ifndef CATCH_CONFIG_NOSTDOUT // If you #define this you must implement these functions std::ostream& cout() { return std::cout; } std::ostream& cerr() { return std::cerr; } std::ostream& clog() { return std::clog; } #endif } #endif // TWOBLUECUBES_CATCH_STREAM_HPP_INCLUDED catch-1.12.1/include/internal/catch_streambuf.h000066400000000000000000000011431325474075300214310ustar00rootroot00000000000000/* * Created by Phil on 27/11/2012. * Copyright 2012 Two Blue Cubes Ltd. All rights reserved. * * Distributed under the Boost Software License, Version 1.0. (See accompanying * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) */ #ifndef TWOBLUECUBES_CATCH_STREAMBUF_H_INCLUDED #define TWOBLUECUBES_CATCH_STREAMBUF_H_INCLUDED #include "catch_compiler_capabilities.h" #include namespace Catch { class StreamBufBase : public std::streambuf { public: virtual ~StreamBufBase() CATCH_NOEXCEPT; }; } #endif // TWOBLUECUBES_CATCH_STREAMBUF_H_INCLUDED catch-1.12.1/include/internal/catch_suppress_warnings.h000066400000000000000000000023041325474075300232350ustar00rootroot00000000000000/* * Copyright 2014 Two Blue Cubes Ltd * * Distributed under the Boost Software License, Version 1.0. (See accompanying * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) */ #ifdef __clang__ # ifdef __ICC // icpc defines the __clang__ macro # pragma warning(push) # pragma warning(disable: 161 1682) # else // __ICC # pragma clang diagnostic ignored "-Wglobal-constructors" # pragma clang diagnostic ignored "-Wvariadic-macros" # pragma clang diagnostic ignored "-Wc99-extensions" # pragma clang diagnostic ignored "-Wunused-variable" # pragma clang diagnostic push # pragma clang diagnostic ignored "-Wpadded" # pragma clang diagnostic ignored "-Wc++98-compat" # pragma clang diagnostic ignored "-Wc++98-compat-pedantic" # pragma clang diagnostic ignored "-Wswitch-enum" # pragma clang diagnostic ignored "-Wcovered-switch-default" # endif #elif defined __GNUC__ # pragma GCC diagnostic ignored "-Wvariadic-macros" # pragma GCC diagnostic ignored "-Wunused-variable" # pragma GCC diagnostic ignored "-Wparentheses" # pragma GCC diagnostic push # pragma GCC diagnostic ignored "-Wpadded" #endif catch-1.12.1/include/internal/catch_tag_alias.h000066400000000000000000000020021325474075300213600ustar00rootroot00000000000000/* * Created by Phil on 27/6/2014. * Copyright 2014 Two Blue Cubes Ltd. All rights reserved. * * Distributed under the Boost Software License, Version 1.0. (See accompanying * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) */ #ifndef TWOBLUECUBES_CATCH_TAG_ALIAS_H_INCLUDED #define TWOBLUECUBES_CATCH_TAG_ALIAS_H_INCLUDED #include "catch_common.h" #include namespace Catch { struct TagAlias { TagAlias( std::string const& _tag, SourceLineInfo _lineInfo ) : tag( _tag ), lineInfo( _lineInfo ) {} std::string tag; SourceLineInfo lineInfo; }; struct RegistrarForTagAliases { RegistrarForTagAliases( char const* alias, char const* tag, SourceLineInfo const& lineInfo ); }; } // end namespace Catch #endif // TWOBLUECUBES_CATCH_TAG_ALIAS_H_INCLUDED #define CATCH_REGISTER_TAG_ALIAS( alias, spec ) namespace{ Catch::RegistrarForTagAliases INTERNAL_CATCH_UNIQUE_NAME( AutoRegisterTagAlias )( alias, spec, CATCH_INTERNAL_LINEINFO ); } catch-1.12.1/include/internal/catch_tag_alias_registry.h000066400000000000000000000017341325474075300233230ustar00rootroot00000000000000/* * Created by Phil on 27/6/2014. * Copyright 2014 Two Blue Cubes Ltd. All rights reserved. * * Distributed under the Boost Software License, Version 1.0. (See accompanying * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) */ #ifndef TWOBLUECUBES_CATCH_TAG_ALIAS_REGISTRY_H_INCLUDED #define TWOBLUECUBES_CATCH_TAG_ALIAS_REGISTRY_H_INCLUDED #include "catch_interfaces_tag_alias_registry.h" #include namespace Catch { class TagAliasRegistry : public ITagAliasRegistry { public: virtual ~TagAliasRegistry(); virtual Option find( std::string const& alias ) const; virtual std::string expandAliases( std::string const& unexpandedTestSpec ) const; void add( std::string const& alias, std::string const& tag, SourceLineInfo const& lineInfo ); private: std::map m_registry; }; } // end namespace Catch #endif // TWOBLUECUBES_CATCH_TAG_ALIAS_REGISTRY_H_INCLUDED catch-1.12.1/include/internal/catch_tag_alias_registry.hpp000066400000000000000000000060671325474075300236670ustar00rootroot00000000000000/* * Created by Phil on 27/6/2014. * Copyright 2014 Two Blue Cubes Ltd. All rights reserved. * * Distributed under the Boost Software License, Version 1.0. (See accompanying * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) */ #ifndef TWOBLUECUBES_CATCH_TAG_ALIAS_REGISTRY_HPP_INCLUDED #define TWOBLUECUBES_CATCH_TAG_ALIAS_REGISTRY_HPP_INCLUDED #include "catch_tag_alias_registry.h" #include "catch_console_colour.hpp" #include "catch_interfaces_registry_hub.h" #include "catch_stream.h" namespace Catch { TagAliasRegistry::~TagAliasRegistry() {} Option TagAliasRegistry::find( std::string const& alias ) const { std::map::const_iterator it = m_registry.find( alias ); if( it != m_registry.end() ) return it->second; else return Option(); } std::string TagAliasRegistry::expandAliases( std::string const& unexpandedTestSpec ) const { std::string expandedTestSpec = unexpandedTestSpec; for( std::map::const_iterator it = m_registry.begin(), itEnd = m_registry.end(); it != itEnd; ++it ) { std::size_t pos = expandedTestSpec.find( it->first ); if( pos != std::string::npos ) { expandedTestSpec = expandedTestSpec.substr( 0, pos ) + it->second.tag + expandedTestSpec.substr( pos + it->first.size() ); } } return expandedTestSpec; } void TagAliasRegistry::add( std::string const& alias, std::string const& tag, SourceLineInfo const& lineInfo ) { if( !startsWith( alias, "[@" ) || !endsWith( alias, ']' ) ) { std::ostringstream oss; oss << Colour( Colour::Red ) << "error: tag alias, \"" << alias << "\" is not of the form [@alias name].\n" << Colour( Colour::FileName ) << lineInfo << '\n'; throw std::domain_error( oss.str().c_str() ); } if( !m_registry.insert( std::make_pair( alias, TagAlias( tag, lineInfo ) ) ).second ) { std::ostringstream oss; oss << Colour( Colour::Red ) << "error: tag alias, \"" << alias << "\" already registered.\n" << "\tFirst seen at " << Colour( Colour::Red ) << find(alias)->lineInfo << '\n' << Colour( Colour::Red ) << "\tRedefined at " << Colour( Colour::FileName) << lineInfo << '\n'; throw std::domain_error( oss.str().c_str() ); } } ITagAliasRegistry::~ITagAliasRegistry() {} ITagAliasRegistry const& ITagAliasRegistry::get() { return getRegistryHub().getTagAliasRegistry(); } RegistrarForTagAliases::RegistrarForTagAliases( char const* alias, char const* tag, SourceLineInfo const& lineInfo ) { getMutableRegistryHub().registerTagAlias( alias, tag, lineInfo ); } } // end namespace Catch #endif // TWOBLUECUBES_CATCH_TAG_ALIAS_REGISTRY_HPP_INCLUDED catch-1.12.1/include/internal/catch_test_case_info.h000066400000000000000000000051321325474075300224300ustar00rootroot00000000000000/* * Created by Phil on 29/10/2010. * Copyright 2010 Two Blue Cubes Ltd. All rights reserved. * * Distributed under the Boost Software License, Version 1.0. (See accompanying * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) */ #ifndef TWOBLUECUBES_CATCH_TEST_CASE_INFO_H_INCLUDED #define TWOBLUECUBES_CATCH_TEST_CASE_INFO_H_INCLUDED #include "catch_common.h" #include "catch_ptr.hpp" #include #include #ifdef __clang__ #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wpadded" #endif namespace Catch { struct ITestCase; struct TestCaseInfo { enum SpecialProperties{ None = 0, IsHidden = 1 << 1, ShouldFail = 1 << 2, MayFail = 1 << 3, Throws = 1 << 4, NonPortable = 1 << 5 }; TestCaseInfo( std::string const& _name, std::string const& _className, std::string const& _description, std::set const& _tags, SourceLineInfo const& _lineInfo ); TestCaseInfo( TestCaseInfo const& other ); friend void setTags( TestCaseInfo& testCaseInfo, std::set const& tags ); bool isHidden() const; bool throws() const; bool okToFail() const; bool expectedToFail() const; std::string name; std::string className; std::string description; std::set tags; std::set lcaseTags; std::string tagsAsString; SourceLineInfo lineInfo; SpecialProperties properties; }; class TestCase : public TestCaseInfo { public: TestCase( ITestCase* testCase, TestCaseInfo const& info ); TestCase( TestCase const& other ); TestCase withName( std::string const& _newName ) const; void invoke() const; TestCaseInfo const& getTestCaseInfo() const; void swap( TestCase& other ); bool operator == ( TestCase const& other ) const; bool operator < ( TestCase const& other ) const; TestCase& operator = ( TestCase const& other ); private: Ptr test; }; TestCase makeTestCase( ITestCase* testCase, std::string const& className, std::string const& name, std::string const& description, SourceLineInfo const& lineInfo ); } #ifdef __clang__ #pragma clang diagnostic pop #endif #endif // TWOBLUECUBES_CATCH_TEST_CASE_INFO_H_INCLUDED catch-1.12.1/include/internal/catch_test_case_info.hpp000066400000000000000000000153101325474075300227670ustar00rootroot00000000000000/* * Created by Phil on 14/08/2012. * Copyright 2012 Two Blue Cubes Ltd. All rights reserved. * * Distributed under the Boost Software License, Version 1.0. (See accompanying * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) */ #ifndef TWOBLUECUBES_CATCH_TEST_CASE_INFO_HPP_INCLUDED #define TWOBLUECUBES_CATCH_TEST_CASE_INFO_HPP_INCLUDED #include "catch_test_spec.hpp" #include "catch_test_case_info.h" #include "catch_interfaces_testcase.h" #include "catch_common.h" #include namespace Catch { inline TestCaseInfo::SpecialProperties parseSpecialTag( std::string const& tag ) { if( startsWith( tag, '.' ) || tag == "hide" || tag == "!hide" ) return TestCaseInfo::IsHidden; else if( tag == "!throws" ) return TestCaseInfo::Throws; else if( tag == "!shouldfail" ) return TestCaseInfo::ShouldFail; else if( tag == "!mayfail" ) return TestCaseInfo::MayFail; else if( tag == "!nonportable" ) return TestCaseInfo::NonPortable; else return TestCaseInfo::None; } inline bool isReservedTag( std::string const& tag ) { return parseSpecialTag( tag ) == TestCaseInfo::None && tag.size() > 0 && !std::isalnum( tag[0] ); } inline void enforceNotReservedTag( std::string const& tag, SourceLineInfo const& _lineInfo ) { if( isReservedTag( tag ) ) { std::ostringstream ss; ss << Colour(Colour::Red) << "Tag name [" << tag << "] not allowed.\n" << "Tag names starting with non alpha-numeric characters are reserved\n" << Colour(Colour::FileName) << _lineInfo << '\n'; throw std::runtime_error(ss.str()); } } TestCase makeTestCase( ITestCase* _testCase, std::string const& _className, std::string const& _name, std::string const& _descOrTags, SourceLineInfo const& _lineInfo ) { bool isHidden( startsWith( _name, "./" ) ); // Legacy support // Parse out tags std::set tags; std::string desc, tag; bool inTag = false; for( std::size_t i = 0; i < _descOrTags.size(); ++i ) { char c = _descOrTags[i]; if( !inTag ) { if( c == '[' ) inTag = true; else desc += c; } else { if( c == ']' ) { TestCaseInfo::SpecialProperties prop = parseSpecialTag( tag ); if( prop == TestCaseInfo::IsHidden ) isHidden = true; else if( prop == TestCaseInfo::None ) enforceNotReservedTag( tag, _lineInfo ); tags.insert( tag ); tag.clear(); inTag = false; } else tag += c; } } if( isHidden ) { tags.insert( "hide" ); tags.insert( "." ); } TestCaseInfo info( _name, _className, desc, tags, _lineInfo ); return TestCase( _testCase, info ); } void setTags( TestCaseInfo& testCaseInfo, std::set const& tags ) { testCaseInfo.tags = tags; testCaseInfo.lcaseTags.clear(); std::ostringstream oss; for( std::set::const_iterator it = tags.begin(), itEnd = tags.end(); it != itEnd; ++it ) { oss << '[' << *it << ']'; std::string lcaseTag = toLower( *it ); testCaseInfo.properties = static_cast( testCaseInfo.properties | parseSpecialTag( lcaseTag ) ); testCaseInfo.lcaseTags.insert( lcaseTag ); } testCaseInfo.tagsAsString = oss.str(); } TestCaseInfo::TestCaseInfo( std::string const& _name, std::string const& _className, std::string const& _description, std::set const& _tags, SourceLineInfo const& _lineInfo ) : name( _name ), className( _className ), description( _description ), lineInfo( _lineInfo ), properties( None ) { setTags( *this, _tags ); } TestCaseInfo::TestCaseInfo( TestCaseInfo const& other ) : name( other.name ), className( other.className ), description( other.description ), tags( other.tags ), lcaseTags( other.lcaseTags ), tagsAsString( other.tagsAsString ), lineInfo( other.lineInfo ), properties( other.properties ) {} bool TestCaseInfo::isHidden() const { return ( properties & IsHidden ) != 0; } bool TestCaseInfo::throws() const { return ( properties & Throws ) != 0; } bool TestCaseInfo::okToFail() const { return ( properties & (ShouldFail | MayFail ) ) != 0; } bool TestCaseInfo::expectedToFail() const { return ( properties & (ShouldFail ) ) != 0; } TestCase::TestCase( ITestCase* testCase, TestCaseInfo const& info ) : TestCaseInfo( info ), test( testCase ) {} TestCase::TestCase( TestCase const& other ) : TestCaseInfo( other ), test( other.test ) {} TestCase TestCase::withName( std::string const& _newName ) const { TestCase other( *this ); other.name = _newName; return other; } void TestCase::swap( TestCase& other ) { test.swap( other.test ); name.swap( other.name ); className.swap( other.className ); description.swap( other.description ); tags.swap( other.tags ); lcaseTags.swap( other.lcaseTags ); tagsAsString.swap( other.tagsAsString ); std::swap( TestCaseInfo::properties, static_cast( other ).properties ); std::swap( lineInfo, other.lineInfo ); } void TestCase::invoke() const { test->invoke(); } bool TestCase::operator == ( TestCase const& other ) const { return test.get() == other.test.get() && name == other.name && className == other.className; } bool TestCase::operator < ( TestCase const& other ) const { return name < other.name; } TestCase& TestCase::operator = ( TestCase const& other ) { TestCase temp( other ); swap( temp ); return *this; } TestCaseInfo const& TestCase::getTestCaseInfo() const { return *this; } } // end namespace Catch #endif // TWOBLUECUBES_CATCH_TEST_CASE_INFO_HPP_INCLUDED catch-1.12.1/include/internal/catch_test_case_registry_impl.hpp000066400000000000000000000163501325474075300247320ustar00rootroot00000000000000/* * Created by Phil on 7/1/2011 * Copyright 2010 Two Blue Cubes Ltd. All rights reserved. * * Distributed under the Boost Software License, Version 1.0. (See accompanying * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) */ #ifndef TWOBLUECUBES_CATCH_TEST_CASE_REGISTRY_IMPL_HPP_INCLUDED #define TWOBLUECUBES_CATCH_TEST_CASE_REGISTRY_IMPL_HPP_INCLUDED #include "catch_test_registry.hpp" #include "catch_test_case_info.h" #include "catch_test_spec.hpp" #include "catch_context.h" #include #include #include #include namespace Catch { struct RandomNumberGenerator { typedef unsigned int result_type; result_type operator()( result_type n ) const { return std::rand() % n; } #ifdef CATCH_CONFIG_CPP11_SHUFFLE static constexpr result_type (min)() { return 0; } static constexpr result_type (max)() { return 1000000; } result_type operator()() const { return std::rand() % (max)(); } #endif template static void shuffle( V& vector ) { RandomNumberGenerator rng; #ifdef CATCH_CONFIG_CPP11_SHUFFLE std::shuffle( vector.begin(), vector.end(), rng ); #else std::random_shuffle( vector.begin(), vector.end(), rng ); #endif } }; inline std::vector sortTests( IConfig const& config, std::vector const& unsortedTestCases ) { std::vector sorted = unsortedTestCases; switch( config.runOrder() ) { case RunTests::InLexicographicalOrder: std::sort( sorted.begin(), sorted.end() ); break; case RunTests::InRandomOrder: { seedRng( config ); RandomNumberGenerator::shuffle( sorted ); } break; case RunTests::InDeclarationOrder: // already in declaration order break; } return sorted; } bool matchTest( TestCase const& testCase, TestSpec const& testSpec, IConfig const& config ) { return testSpec.matches( testCase ) && ( config.allowThrows() || !testCase.throws() ); } void enforceNoDuplicateTestCases( std::vector const& functions ) { std::set seenFunctions; for( std::vector::const_iterator it = functions.begin(), itEnd = functions.end(); it != itEnd; ++it ) { std::pair::const_iterator, bool> prev = seenFunctions.insert( *it ); if( !prev.second ) { std::ostringstream ss; ss << Colour( Colour::Red ) << "error: TEST_CASE( \"" << it->name << "\" ) already defined.\n" << "\tFirst seen at " << prev.first->getTestCaseInfo().lineInfo << '\n' << "\tRedefined at " << it->getTestCaseInfo().lineInfo << std::endl; throw std::runtime_error(ss.str()); } } } std::vector filterTests( std::vector const& testCases, TestSpec const& testSpec, IConfig const& config ) { std::vector filtered; filtered.reserve( testCases.size() ); for( std::vector::const_iterator it = testCases.begin(), itEnd = testCases.end(); it != itEnd; ++it ) if( matchTest( *it, testSpec, config ) ) filtered.push_back( *it ); return filtered; } std::vector const& getAllTestCasesSorted( IConfig const& config ) { return getRegistryHub().getTestCaseRegistry().getAllTestsSorted( config ); } class TestRegistry : public ITestCaseRegistry { public: TestRegistry() : m_currentSortOrder( RunTests::InDeclarationOrder ), m_unnamedCount( 0 ) {} virtual ~TestRegistry(); virtual void registerTest( TestCase const& testCase ) { std::string name = testCase.getTestCaseInfo().name; if( name.empty() ) { std::ostringstream oss; oss << "Anonymous test case " << ++m_unnamedCount; return registerTest( testCase.withName( oss.str() ) ); } m_functions.push_back( testCase ); } virtual std::vector const& getAllTests() const { return m_functions; } virtual std::vector const& getAllTestsSorted( IConfig const& config ) const { if( m_sortedFunctions.empty() ) enforceNoDuplicateTestCases( m_functions ); if( m_currentSortOrder != config.runOrder() || m_sortedFunctions.empty() ) { m_sortedFunctions = sortTests( config, m_functions ); m_currentSortOrder = config.runOrder(); } return m_sortedFunctions; } private: std::vector m_functions; mutable RunTests::InWhatOrder m_currentSortOrder; mutable std::vector m_sortedFunctions; size_t m_unnamedCount; std::ios_base::Init m_ostreamInit; // Forces cout/ cerr to be initialised }; /////////////////////////////////////////////////////////////////////////// class FreeFunctionTestCase : public SharedImpl { public: FreeFunctionTestCase( TestFunction fun ) : m_fun( fun ) {} virtual void invoke() const { m_fun(); } private: virtual ~FreeFunctionTestCase(); TestFunction m_fun; }; inline std::string extractClassName( std::string const& classOrQualifiedMethodName ) { std::string className = classOrQualifiedMethodName; if( startsWith( className, '&' ) ) { std::size_t lastColons = className.rfind( "::" ); std::size_t penultimateColons = className.rfind( "::", lastColons-1 ); if( penultimateColons == std::string::npos ) penultimateColons = 1; className = className.substr( penultimateColons, lastColons-penultimateColons ); } return className; } void registerTestCase ( ITestCase* testCase, char const* classOrQualifiedMethodName, NameAndDesc const& nameAndDesc, SourceLineInfo const& lineInfo ) { getMutableRegistryHub().registerTest ( makeTestCase ( testCase, extractClassName( classOrQualifiedMethodName ), nameAndDesc.name, nameAndDesc.description, lineInfo ) ); } void registerTestCaseFunction ( TestFunction function, SourceLineInfo const& lineInfo, NameAndDesc const& nameAndDesc ) { registerTestCase( new FreeFunctionTestCase( function ), "", nameAndDesc, lineInfo ); } /////////////////////////////////////////////////////////////////////////// AutoReg::AutoReg ( TestFunction function, SourceLineInfo const& lineInfo, NameAndDesc const& nameAndDesc ) { registerTestCaseFunction( function, lineInfo, nameAndDesc ); } AutoReg::~AutoReg() {} } // end namespace Catch #endif // TWOBLUECUBES_CATCH_TEST_CASE_REGISTRY_IMPL_HPP_INCLUDED catch-1.12.1/include/internal/catch_test_case_tracker.hpp000066400000000000000000000300321325474075300234650ustar00rootroot00000000000000/* * Created by Phil Nash on 23/7/2013 * Copyright 2013 Two Blue Cubes Ltd. All rights reserved. * * Distributed under the Boost Software License, Version 1.0. (See accompanying * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) */ #ifndef TWOBLUECUBES_CATCH_TEST_CASE_TRACKER_HPP_INCLUDED #define TWOBLUECUBES_CATCH_TEST_CASE_TRACKER_HPP_INCLUDED #include "catch_compiler_capabilities.h" #include "catch_ptr.hpp" #include #include #include #include #include CATCH_INTERNAL_SUPPRESS_ETD_WARNINGS namespace Catch { namespace TestCaseTracking { struct NameAndLocation { std::string name; SourceLineInfo location; NameAndLocation( std::string const& _name, SourceLineInfo const& _location ) : name( _name ), location( _location ) {} }; struct ITracker : SharedImpl<> { virtual ~ITracker(); // static queries virtual NameAndLocation const& nameAndLocation() const = 0; // dynamic queries virtual bool isComplete() const = 0; // Successfully completed or failed virtual bool isSuccessfullyCompleted() const = 0; virtual bool isOpen() const = 0; // Started but not complete virtual bool hasChildren() const = 0; virtual ITracker& parent() = 0; // actions virtual void close() = 0; // Successfully complete virtual void fail() = 0; virtual void markAsNeedingAnotherRun() = 0; virtual void addChild( Ptr const& child ) = 0; virtual ITracker* findChild( NameAndLocation const& nameAndLocation ) = 0; virtual void openChild() = 0; // Debug/ checking virtual bool isSectionTracker() const = 0; virtual bool isIndexTracker() const = 0; }; class TrackerContext { enum RunState { NotStarted, Executing, CompletedCycle }; Ptr m_rootTracker; ITracker* m_currentTracker; RunState m_runState; public: static TrackerContext& instance() { static TrackerContext s_instance; return s_instance; } TrackerContext() : m_currentTracker( CATCH_NULL ), m_runState( NotStarted ) {} ITracker& startRun(); void endRun() { m_rootTracker.reset(); m_currentTracker = CATCH_NULL; m_runState = NotStarted; } void startCycle() { m_currentTracker = m_rootTracker.get(); m_runState = Executing; } void completeCycle() { m_runState = CompletedCycle; } bool completedCycle() const { return m_runState == CompletedCycle; } ITracker& currentTracker() { return *m_currentTracker; } void setCurrentTracker( ITracker* tracker ) { m_currentTracker = tracker; } }; class TrackerBase : public ITracker { protected: enum CycleState { NotStarted, Executing, ExecutingChildren, NeedsAnotherRun, CompletedSuccessfully, Failed }; class TrackerHasName { NameAndLocation m_nameAndLocation; public: TrackerHasName( NameAndLocation const& nameAndLocation ) : m_nameAndLocation( nameAndLocation ) {} bool operator ()( Ptr const& tracker ) { return tracker->nameAndLocation().name == m_nameAndLocation.name && tracker->nameAndLocation().location == m_nameAndLocation.location; } }; typedef std::vector > Children; NameAndLocation m_nameAndLocation; TrackerContext& m_ctx; ITracker* m_parent; Children m_children; CycleState m_runState; public: TrackerBase( NameAndLocation const& nameAndLocation, TrackerContext& ctx, ITracker* parent ) : m_nameAndLocation( nameAndLocation ), m_ctx( ctx ), m_parent( parent ), m_runState( NotStarted ) {} virtual ~TrackerBase(); virtual NameAndLocation const& nameAndLocation() const CATCH_OVERRIDE { return m_nameAndLocation; } virtual bool isComplete() const CATCH_OVERRIDE { return m_runState == CompletedSuccessfully || m_runState == Failed; } virtual bool isSuccessfullyCompleted() const CATCH_OVERRIDE { return m_runState == CompletedSuccessfully; } virtual bool isOpen() const CATCH_OVERRIDE { return m_runState != NotStarted && !isComplete(); } virtual bool hasChildren() const CATCH_OVERRIDE { return !m_children.empty(); } virtual void addChild( Ptr const& child ) CATCH_OVERRIDE { m_children.push_back( child ); } virtual ITracker* findChild( NameAndLocation const& nameAndLocation ) CATCH_OVERRIDE { Children::const_iterator it = std::find_if( m_children.begin(), m_children.end(), TrackerHasName( nameAndLocation ) ); return( it != m_children.end() ) ? it->get() : CATCH_NULL; } virtual ITracker& parent() CATCH_OVERRIDE { assert( m_parent ); // Should always be non-null except for root return *m_parent; } virtual void openChild() CATCH_OVERRIDE { if( m_runState != ExecutingChildren ) { m_runState = ExecutingChildren; if( m_parent ) m_parent->openChild(); } } virtual bool isSectionTracker() const CATCH_OVERRIDE { return false; } virtual bool isIndexTracker() const CATCH_OVERRIDE { return false; } void open() { m_runState = Executing; moveToThis(); if( m_parent ) m_parent->openChild(); } virtual void close() CATCH_OVERRIDE { // Close any still open children (e.g. generators) while( &m_ctx.currentTracker() != this ) m_ctx.currentTracker().close(); switch( m_runState ) { case NotStarted: case CompletedSuccessfully: case Failed: throw std::logic_error( "Illogical state" ); case NeedsAnotherRun: break;; case Executing: m_runState = CompletedSuccessfully; break; case ExecutingChildren: if( m_children.empty() || m_children.back()->isComplete() ) m_runState = CompletedSuccessfully; break; default: throw std::logic_error( "Unexpected state" ); } moveToParent(); m_ctx.completeCycle(); } virtual void fail() CATCH_OVERRIDE { m_runState = Failed; if( m_parent ) m_parent->markAsNeedingAnotherRun(); moveToParent(); m_ctx.completeCycle(); } virtual void markAsNeedingAnotherRun() CATCH_OVERRIDE { m_runState = NeedsAnotherRun; } private: void moveToParent() { assert( m_parent ); m_ctx.setCurrentTracker( m_parent ); } void moveToThis() { m_ctx.setCurrentTracker( this ); } }; class SectionTracker : public TrackerBase { std::vector m_filters; public: SectionTracker( NameAndLocation const& nameAndLocation, TrackerContext& ctx, ITracker* parent ) : TrackerBase( nameAndLocation, ctx, parent ) { if( parent ) { while( !parent->isSectionTracker() ) parent = &parent->parent(); SectionTracker& parentSection = static_cast( *parent ); addNextFilters( parentSection.m_filters ); } } virtual ~SectionTracker(); virtual bool isSectionTracker() const CATCH_OVERRIDE { return true; } static SectionTracker& acquire( TrackerContext& ctx, NameAndLocation const& nameAndLocation ) { SectionTracker* section = CATCH_NULL; ITracker& currentTracker = ctx.currentTracker(); if( ITracker* childTracker = currentTracker.findChild( nameAndLocation ) ) { assert( childTracker ); assert( childTracker->isSectionTracker() ); section = static_cast( childTracker ); } else { section = new SectionTracker( nameAndLocation, ctx, ¤tTracker ); currentTracker.addChild( section ); } if( !ctx.completedCycle() ) section->tryOpen(); return *section; } void tryOpen() { if( !isComplete() && (m_filters.empty() || m_filters[0].empty() || m_filters[0] == m_nameAndLocation.name ) ) open(); } void addInitialFilters( std::vector const& filters ) { if( !filters.empty() ) { m_filters.push_back(""); // Root - should never be consulted m_filters.push_back(""); // Test Case - not a section filter m_filters.insert( m_filters.end(), filters.begin(), filters.end() ); } } void addNextFilters( std::vector const& filters ) { if( filters.size() > 1 ) m_filters.insert( m_filters.end(), ++filters.begin(), filters.end() ); } }; class IndexTracker : public TrackerBase { int m_size; int m_index; public: IndexTracker( NameAndLocation const& nameAndLocation, TrackerContext& ctx, ITracker* parent, int size ) : TrackerBase( nameAndLocation, ctx, parent ), m_size( size ), m_index( -1 ) {} virtual ~IndexTracker(); virtual bool isIndexTracker() const CATCH_OVERRIDE { return true; } static IndexTracker& acquire( TrackerContext& ctx, NameAndLocation const& nameAndLocation, int size ) { IndexTracker* tracker = CATCH_NULL; ITracker& currentTracker = ctx.currentTracker(); if( ITracker* childTracker = currentTracker.findChild( nameAndLocation ) ) { assert( childTracker ); assert( childTracker->isIndexTracker() ); tracker = static_cast( childTracker ); } else { tracker = new IndexTracker( nameAndLocation, ctx, ¤tTracker, size ); currentTracker.addChild( tracker ); } if( !ctx.completedCycle() && !tracker->isComplete() ) { if( tracker->m_runState != ExecutingChildren && tracker->m_runState != NeedsAnotherRun ) tracker->moveNext(); tracker->open(); } return *tracker; } int index() const { return m_index; } void moveNext() { m_index++; m_children.clear(); } virtual void close() CATCH_OVERRIDE { TrackerBase::close(); if( m_runState == CompletedSuccessfully && m_index < m_size-1 ) m_runState = Executing; } }; inline ITracker& TrackerContext::startRun() { m_rootTracker = new SectionTracker( NameAndLocation( "{root}", CATCH_INTERNAL_LINEINFO ), *this, CATCH_NULL ); m_currentTracker = CATCH_NULL; m_runState = Executing; return *m_rootTracker; } } // namespace TestCaseTracking using TestCaseTracking::ITracker; using TestCaseTracking::TrackerContext; using TestCaseTracking::SectionTracker; using TestCaseTracking::IndexTracker; } // namespace Catch CATCH_INTERNAL_UNSUPPRESS_ETD_WARNINGS #endif // TWOBLUECUBES_CATCH_TEST_CASE_TRACKER_HPP_INCLUDED catch-1.12.1/include/internal/catch_test_registry.hpp000066400000000000000000000146641325474075300227240ustar00rootroot00000000000000/* * Created by Phil on 18/10/2010. * Copyright 2010 Two Blue Cubes Ltd. All rights reserved. * * Distributed under the Boost Software License, Version 1.0. (See accompanying * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) */ #ifndef TWOBLUECUBES_CATCH_TEST_REGISTRY_HPP_INCLUDED #define TWOBLUECUBES_CATCH_TEST_REGISTRY_HPP_INCLUDED #include "catch_common.h" #include "catch_interfaces_testcase.h" #include "catch_compiler_capabilities.h" namespace Catch { template class MethodTestCase : public SharedImpl { public: MethodTestCase( void (C::*method)() ) : m_method( method ) {} virtual void invoke() const { C obj; (obj.*m_method)(); } private: virtual ~MethodTestCase() {} void (C::*m_method)(); }; typedef void(*TestFunction)(); struct NameAndDesc { NameAndDesc( const char* _name = "", const char* _description= "" ) : name( _name ), description( _description ) {} const char* name; const char* description; }; void registerTestCase ( ITestCase* testCase, char const* className, NameAndDesc const& nameAndDesc, SourceLineInfo const& lineInfo ); struct AutoReg { AutoReg ( TestFunction function, SourceLineInfo const& lineInfo, NameAndDesc const& nameAndDesc ); template AutoReg ( void (C::*method)(), char const* className, NameAndDesc const& nameAndDesc, SourceLineInfo const& lineInfo ) { registerTestCase ( new MethodTestCase( method ), className, nameAndDesc, lineInfo ); } ~AutoReg(); private: AutoReg( AutoReg const& ); void operator= ( AutoReg const& ); }; void registerTestCaseFunction ( TestFunction function, SourceLineInfo const& lineInfo, NameAndDesc const& nameAndDesc ); } // end namespace Catch #ifdef CATCH_CONFIG_VARIADIC_MACROS /////////////////////////////////////////////////////////////////////////////// #define INTERNAL_CATCH_TESTCASE2( TestName, ... ) \ static void TestName(); \ CATCH_INTERNAL_SUPPRESS_ETD_WARNINGS \ namespace{ Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( &TestName, CATCH_INTERNAL_LINEINFO, Catch::NameAndDesc( __VA_ARGS__ ) ); } /* NOLINT */ \ CATCH_INTERNAL_UNSUPPRESS_ETD_WARNINGS \ static void TestName() #define INTERNAL_CATCH_TESTCASE( ... ) \ INTERNAL_CATCH_TESTCASE2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ), __VA_ARGS__ ) /////////////////////////////////////////////////////////////////////////////// #define INTERNAL_CATCH_METHOD_AS_TEST_CASE( QualifiedMethod, ... ) \ CATCH_INTERNAL_SUPPRESS_ETD_WARNINGS \ namespace{ Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( &QualifiedMethod, "&" #QualifiedMethod, Catch::NameAndDesc( __VA_ARGS__ ), CATCH_INTERNAL_LINEINFO ); } /* NOLINT */ \ CATCH_INTERNAL_UNSUPPRESS_ETD_WARNINGS /////////////////////////////////////////////////////////////////////////////// #define INTERNAL_CATCH_TEST_CASE_METHOD2( TestName, ClassName, ... )\ CATCH_INTERNAL_SUPPRESS_ETD_WARNINGS \ namespace{ \ struct TestName : ClassName{ \ void test(); \ }; \ Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar ) ( &TestName::test, #ClassName, Catch::NameAndDesc( __VA_ARGS__ ), CATCH_INTERNAL_LINEINFO ); /* NOLINT */ \ } \ CATCH_INTERNAL_UNSUPPRESS_ETD_WARNINGS \ void TestName::test() #define INTERNAL_CATCH_TEST_CASE_METHOD( ClassName, ... ) \ INTERNAL_CATCH_TEST_CASE_METHOD2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ), ClassName, __VA_ARGS__ ) /////////////////////////////////////////////////////////////////////////////// #define INTERNAL_CATCH_REGISTER_TESTCASE( Function, ... ) \ CATCH_INTERNAL_SUPPRESS_ETD_WARNINGS \ Catch::AutoReg( Function, CATCH_INTERNAL_LINEINFO, Catch::NameAndDesc( __VA_ARGS__ ) ); /* NOLINT */ \ CATCH_INTERNAL_UNSUPPRESS_ETD_WARNINGS #else /////////////////////////////////////////////////////////////////////////////// #define INTERNAL_CATCH_TESTCASE2( TestName, Name, Desc ) \ static void TestName(); \ CATCH_INTERNAL_SUPPRESS_ETD_WARNINGS \ namespace{ Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( &TestName, CATCH_INTERNAL_LINEINFO, Catch::NameAndDesc( Name, Desc ) ); } /* NOLINT */ \ CATCH_INTERNAL_UNSUPPRESS_ETD_WARNINGS \ static void TestName() #define INTERNAL_CATCH_TESTCASE( Name, Desc ) \ INTERNAL_CATCH_TESTCASE2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ), Name, Desc ) /////////////////////////////////////////////////////////////////////////////// #define INTERNAL_CATCH_METHOD_AS_TEST_CASE( QualifiedMethod, Name, Desc ) \ CATCH_INTERNAL_SUPPRESS_ETD_WARNINGS \ namespace{ Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( &QualifiedMethod, "&" #QualifiedMethod, Catch::NameAndDesc( Name, Desc ), CATCH_INTERNAL_LINEINFO ); } /* NOLINT */ \ CATCH_INTERNAL_UNSUPPRESS_ETD_WARNINGS /////////////////////////////////////////////////////////////////////////////// #define INTERNAL_CATCH_TEST_CASE_METHOD2( TestCaseName, ClassName, TestName, Desc )\ CATCH_INTERNAL_SUPPRESS_ETD_WARNINGS \ namespace{ \ struct TestCaseName : ClassName{ \ void test(); \ }; \ Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar ) ( &TestCaseName::test, #ClassName, Catch::NameAndDesc( TestName, Desc ), CATCH_INTERNAL_LINEINFO ); /* NOLINT */ \ } \ CATCH_INTERNAL_UNSUPPRESS_ETD_WARNINGS \ void TestCaseName::test() #define INTERNAL_CATCH_TEST_CASE_METHOD( ClassName, TestName, Desc )\ INTERNAL_CATCH_TEST_CASE_METHOD2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ), ClassName, TestName, Desc ) /////////////////////////////////////////////////////////////////////////////// #define INTERNAL_CATCH_REGISTER_TESTCASE( Function, Name, Desc ) \ CATCH_INTERNAL_SUPPRESS_ETD_WARNINGS \ Catch::AutoReg( Function, CATCH_INTERNAL_LINEINFO, Catch::NameAndDesc( Name, Desc ) ); /* NOLINT */ \ CATCH_INTERNAL_UNSUPPRESS_ETD_WARNINGS #endif #endif // TWOBLUECUBES_CATCH_TEST_REGISTRY_HPP_INCLUDED catch-1.12.1/include/internal/catch_test_spec.hpp000066400000000000000000000062621325474075300220010ustar00rootroot00000000000000/* * Created by Phil on 14/8/2012. * Copyright 2010 Two Blue Cubes Ltd. All rights reserved. * * Distributed under the Boost Software License, Version 1.0. (See accompanying * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) */ #ifndef TWOBLUECUBES_CATCH_TEST_SPEC_HPP_INCLUDED #define TWOBLUECUBES_CATCH_TEST_SPEC_HPP_INCLUDED #ifdef __clang__ #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wpadded" #endif #include "catch_wildcard_pattern.hpp" #include "catch_test_case_info.h" #include #include namespace Catch { class TestSpec { struct Pattern : SharedImpl<> { virtual ~Pattern(); virtual bool matches( TestCaseInfo const& testCase ) const = 0; }; class NamePattern : public Pattern { public: NamePattern( std::string const& name ) : m_wildcardPattern( toLower( name ), CaseSensitive::No ) {} virtual ~NamePattern(); virtual bool matches( TestCaseInfo const& testCase ) const { return m_wildcardPattern.matches( toLower( testCase.name ) ); } private: WildcardPattern m_wildcardPattern; }; class TagPattern : public Pattern { public: TagPattern( std::string const& tag ) : m_tag( toLower( tag ) ) {} virtual ~TagPattern(); virtual bool matches( TestCaseInfo const& testCase ) const { return testCase.lcaseTags.find( m_tag ) != testCase.lcaseTags.end(); } private: std::string m_tag; }; class ExcludedPattern : public Pattern { public: ExcludedPattern( Ptr const& underlyingPattern ) : m_underlyingPattern( underlyingPattern ) {} virtual ~ExcludedPattern(); virtual bool matches( TestCaseInfo const& testCase ) const { return !m_underlyingPattern->matches( testCase ); } private: Ptr m_underlyingPattern; }; struct Filter { std::vector > m_patterns; bool matches( TestCaseInfo const& testCase ) const { // All patterns in a filter must match for the filter to be a match for( std::vector >::const_iterator it = m_patterns.begin(), itEnd = m_patterns.end(); it != itEnd; ++it ) { if( !(*it)->matches( testCase ) ) return false; } return true; } }; public: bool hasFilters() const { return !m_filters.empty(); } bool matches( TestCaseInfo const& testCase ) const { // A TestSpec matches if any filter matches for( std::vector::const_iterator it = m_filters.begin(), itEnd = m_filters.end(); it != itEnd; ++it ) if( it->matches( testCase ) ) return true; return false; } private: std::vector m_filters; friend class TestSpecParser; }; } #ifdef __clang__ #pragma clang diagnostic pop #endif #endif // TWOBLUECUBES_CATCH_TEST_SPEC_HPP_INCLUDED catch-1.12.1/include/internal/catch_test_spec_parser.hpp000066400000000000000000000111631325474075300233510ustar00rootroot00000000000000/* * Created by Phil on 15/5/2013. * Copyright 2014 Two Blue Cubes Ltd. All rights reserved. * * Distributed under the Boost Software License, Version 1.0. (See accompanying * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) */ #ifndef TWOBLUECUBES_CATCH_TEST_SPEC_PARSER_HPP_INCLUDED #define TWOBLUECUBES_CATCH_TEST_SPEC_PARSER_HPP_INCLUDED #ifdef __clang__ #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wpadded" #endif #include "catch_test_spec.hpp" #include "catch_interfaces_tag_alias_registry.h" namespace Catch { class TestSpecParser { enum Mode{ None, Name, QuotedName, Tag, EscapedName }; Mode m_mode; bool m_exclusion; std::size_t m_start, m_pos; std::string m_arg; std::vector m_escapeChars; TestSpec::Filter m_currentFilter; TestSpec m_testSpec; ITagAliasRegistry const* m_tagAliases; public: TestSpecParser( ITagAliasRegistry const& tagAliases ) :m_mode(None), m_exclusion(false), m_start(0), m_pos(0), m_tagAliases( &tagAliases ) {} TestSpecParser& parse( std::string const& arg ) { m_mode = None; m_exclusion = false; m_start = std::string::npos; m_arg = m_tagAliases->expandAliases( arg ); m_escapeChars.clear(); for( m_pos = 0; m_pos < m_arg.size(); ++m_pos ) visitChar( m_arg[m_pos] ); if( m_mode == Name ) addPattern(); return *this; } TestSpec testSpec() { addFilter(); return m_testSpec; } private: void visitChar( char c ) { if( m_mode == None ) { switch( c ) { case ' ': return; case '~': m_exclusion = true; return; case '[': return startNewMode( Tag, ++m_pos ); case '"': return startNewMode( QuotedName, ++m_pos ); case '\\': return escape(); default: startNewMode( Name, m_pos ); break; } } if( m_mode == Name ) { if( c == ',' ) { addPattern(); addFilter(); } else if( c == '[' ) { if( subString() == "exclude:" ) m_exclusion = true; else addPattern(); startNewMode( Tag, ++m_pos ); } else if( c == '\\' ) escape(); } else if( m_mode == EscapedName ) m_mode = Name; else if( m_mode == QuotedName && c == '"' ) addPattern(); else if( m_mode == Tag && c == ']' ) addPattern(); } void startNewMode( Mode mode, std::size_t start ) { m_mode = mode; m_start = start; } void escape() { if( m_mode == None ) m_start = m_pos; m_mode = EscapedName; m_escapeChars.push_back( m_pos ); } std::string subString() const { return m_arg.substr( m_start, m_pos - m_start ); } template void addPattern() { std::string token = subString(); for( size_t i = 0; i < m_escapeChars.size(); ++i ) token = token.substr( 0, m_escapeChars[i]-m_start-i ) + token.substr( m_escapeChars[i]-m_start-i+1 ); m_escapeChars.clear(); if( startsWith( token, "exclude:" ) ) { m_exclusion = true; token = token.substr( 8 ); } if( !token.empty() ) { Ptr pattern = new T( token ); if( m_exclusion ) pattern = new TestSpec::ExcludedPattern( pattern ); m_currentFilter.m_patterns.push_back( pattern ); } m_exclusion = false; m_mode = None; } void addFilter() { if( !m_currentFilter.m_patterns.empty() ) { m_testSpec.m_filters.push_back( m_currentFilter ); m_currentFilter = TestSpec::Filter(); } } }; inline TestSpec parseTestSpec( std::string const& arg ) { return TestSpecParser( ITagAliasRegistry::get() ).parse( arg ).testSpec(); } } // namespace Catch #ifdef __clang__ #pragma clang diagnostic pop #endif #endif // TWOBLUECUBES_CATCH_TEST_SPEC_PARSER_HPP_INCLUDED catch-1.12.1/include/internal/catch_text.h000066400000000000000000000012741325474075300204320ustar00rootroot00000000000000/* * Created by Phil on 10/2/2014. * Copyright 2014 Two Blue Cubes Ltd. All rights reserved. * * Distributed under the Boost Software License, Version 1.0. (See accompanying * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) */ #ifndef TWOBLUECUBES_CATCH_TEXT_H_INCLUDED #define TWOBLUECUBES_CATCH_TEXT_H_INCLUDED #include "catch_config.hpp" #define TBC_TEXT_FORMAT_CONSOLE_WIDTH CATCH_CONFIG_CONSOLE_WIDTH #define CLICHE_TBC_TEXT_FORMAT_OUTER_NAMESPACE Catch #include "../external/tbc_text_format.h" #undef CLICHE_TBC_TEXT_FORMAT_OUTER_NAMESPACE namespace Catch { using Tbc::Text; using Tbc::TextAttributes; } #endif // TWOBLUECUBES_CATCH_TEXT_H_INCLUDED catch-1.12.1/include/internal/catch_timer.h000066400000000000000000000016101325474075300205600ustar00rootroot00000000000000/* * Created by Phil on 05/08/2013. * Copyright 2013 Two Blue Cubes Ltd. All rights reserved. * * Distributed under the Boost Software License, Version 1.0. (See accompanying * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) */ #ifndef TWOBLUECUBES_CATCH_TIMER_H_INCLUDED #define TWOBLUECUBES_CATCH_TIMER_H_INCLUDED #include "catch_platform.h" #ifdef _MSC_VER namespace Catch { typedef unsigned long long UInt64; } #else #include namespace Catch { typedef uint64_t UInt64; } #endif namespace Catch { class Timer { public: Timer() : m_ticks( 0 ) {} void start(); unsigned int getElapsedMicroseconds() const; unsigned int getElapsedMilliseconds() const; double getElapsedSeconds() const; private: UInt64 m_ticks; }; } // namespace Catch #endif // TWOBLUECUBES_CATCH_TIMER_H_INCLUDED catch-1.12.1/include/internal/catch_timer.hpp000066400000000000000000000033601325474075300211240ustar00rootroot00000000000000/* * Created by Phil on 05/08/2013. * Copyright 2013 Two Blue Cubes Ltd. All rights reserved. * * Distributed under the Boost Software License, Version 1.0. (See accompanying * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) */ #include "catch_timer.h" #include "catch_platform.h" #ifdef __clang__ #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wc++11-long-long" #endif #ifdef CATCH_PLATFORM_WINDOWS # include "catch_windows_h_proxy.h" #else #include #endif namespace Catch { namespace { #ifdef CATCH_PLATFORM_WINDOWS UInt64 getCurrentTicks() { static UInt64 hz=0, hzo=0; if (!hz) { QueryPerformanceFrequency( reinterpret_cast( &hz ) ); QueryPerformanceCounter( reinterpret_cast( &hzo ) ); } UInt64 t; QueryPerformanceCounter( reinterpret_cast( &t ) ); return ((t-hzo)*1000000)/hz; } #else UInt64 getCurrentTicks() { timeval t; gettimeofday(&t,CATCH_NULL); return static_cast( t.tv_sec ) * 1000000ull + static_cast( t.tv_usec ); } #endif } void Timer::start() { m_ticks = getCurrentTicks(); } unsigned int Timer::getElapsedMicroseconds() const { return static_cast(getCurrentTicks() - m_ticks); } unsigned int Timer::getElapsedMilliseconds() const { return static_cast(getElapsedMicroseconds()/1000); } double Timer::getElapsedSeconds() const { return getElapsedMicroseconds()/1000000.0; } } // namespace Catch #ifdef __clang__ #pragma clang diagnostic pop #endif catch-1.12.1/include/internal/catch_tostring.h000066400000000000000000000165771325474075300213330ustar00rootroot00000000000000/* * Created by Phil on 8/5/2012. * Copyright 2012 Two Blue Cubes Ltd. All rights reserved. * * Distributed under the Boost Software License, Version 1.0. (See accompanying * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) */ #ifndef TWOBLUECUBES_CATCH_TOSTRING_H_INCLUDED #define TWOBLUECUBES_CATCH_TOSTRING_H_INCLUDED #include "catch_common.h" #include #include #include #include #include #ifdef __OBJC__ #include "catch_objc_arc.hpp" #endif #ifdef CATCH_CONFIG_CPP11_TUPLE #include #endif #ifdef CATCH_CONFIG_CPP11_IS_ENUM #include #endif namespace Catch { // Why we're here. template std::string toString( T const& value ); // Built in overloads std::string toString( std::string const& value ); std::string toString( std::wstring const& value ); std::string toString( const char* const value ); std::string toString( char* const value ); std::string toString( const wchar_t* const value ); std::string toString( wchar_t* const value ); std::string toString( int value ); std::string toString( unsigned long value ); std::string toString( unsigned int value ); std::string toString( const double value ); std::string toString( const float value ); std::string toString( bool value ); std::string toString( char value ); std::string toString( signed char value ); std::string toString( unsigned char value ); #ifdef CATCH_CONFIG_CPP11_LONG_LONG std::string toString( long long value ); std::string toString( unsigned long long value ); #endif #ifdef CATCH_CONFIG_CPP11_NULLPTR std::string toString( std::nullptr_t ); #endif #ifdef __OBJC__ std::string toString( NSString const * const& nsstring ); std::string toString( NSString * CATCH_ARC_STRONG & nsstring ); std::string toString( NSObject* const& nsObject ); #endif namespace Detail { extern const std::string unprintableString; #if !defined(CATCH_CONFIG_CPP11_STREAM_INSERTABLE_CHECK) struct BorgType { template BorgType( T const& ); }; struct TrueType { char sizer[1]; }; struct FalseType { char sizer[2]; }; TrueType& testStreamable( std::ostream& ); FalseType testStreamable( FalseType ); FalseType operator<<( std::ostream const&, BorgType const& ); template struct IsStreamInsertable { static std::ostream &s; static T const&t; enum { value = sizeof( testStreamable(s << t) ) == sizeof( TrueType ) }; }; #else template class IsStreamInsertable { template static auto test(int) -> decltype( std::declval() << std::declval(), std::true_type() ); template static auto test(...) -> std::false_type; public: static const bool value = decltype(test(0))::value; }; #endif #if defined(CATCH_CONFIG_CPP11_IS_ENUM) template::value > struct EnumStringMaker { static std::string convert( T const& ) { return unprintableString; } }; template struct EnumStringMaker { static std::string convert( T const& v ) { return ::Catch::toString( static_cast::type>(v) ); } }; #endif template struct StringMakerBase { #if defined(CATCH_CONFIG_CPP11_IS_ENUM) template static std::string convert( T const& v ) { return EnumStringMaker::convert( v ); } #else template static std::string convert( T const& ) { return unprintableString; } #endif }; template<> struct StringMakerBase { template static std::string convert( T const& _value ) { std::ostringstream oss; oss << _value; return oss.str(); } }; std::string rawMemoryToString( const void *object, std::size_t size ); template std::string rawMemoryToString( const T& object ) { return rawMemoryToString( &object, sizeof(object) ); } } // end namespace Detail template struct StringMaker : Detail::StringMakerBase::value> {}; template struct StringMaker { template static std::string convert( U* p ) { if( !p ) return "NULL"; else return Detail::rawMemoryToString( p ); } }; template struct StringMaker { static std::string convert( R C::* p ) { if( !p ) return "NULL"; else return Detail::rawMemoryToString( p ); } }; namespace Detail { template std::string rangeToString( InputIterator first, InputIterator last ); } //template //struct StringMaker > { // static std::string convert( std::vector const& v ) { // return Detail::rangeToString( v.begin(), v.end() ); // } //}; template std::string toString( std::vector const& v ) { return Detail::rangeToString( v.begin(), v.end() ); } #ifdef CATCH_CONFIG_CPP11_TUPLE // toString for tuples namespace TupleDetail { template< typename Tuple, std::size_t N = 0, bool = (N < std::tuple_size::value) > struct ElementPrinter { static void print( const Tuple& tuple, std::ostream& os ) { os << ( N ? ", " : " " ) << Catch::toString(std::get(tuple)); ElementPrinter::print(tuple,os); } }; template< typename Tuple, std::size_t N > struct ElementPrinter { static void print( const Tuple&, std::ostream& ) {} }; } template struct StringMaker> { static std::string convert( const std::tuple& tuple ) { std::ostringstream os; os << '{'; TupleDetail::ElementPrinter>::print( tuple, os ); os << " }"; return os.str(); } }; #endif // CATCH_CONFIG_CPP11_TUPLE namespace Detail { template std::string makeString( T const& value ) { return StringMaker::convert( value ); } } // end namespace Detail /// \brief converts any type to a string /// /// The default template forwards on to ostringstream - except when an /// ostringstream overload does not exist - in which case it attempts to detect /// that and writes {?}. /// Overload (not specialise) this template for custom typs that you don't want /// to provide an ostream overload for. template std::string toString( T const& value ) { return StringMaker::convert( value ); } namespace Detail { template std::string rangeToString( InputIterator first, InputIterator last ) { std::ostringstream oss; oss << "{ "; if( first != last ) { oss << Catch::toString( *first ); for( ++first ; first != last ; ++first ) oss << ", " << Catch::toString( *first ); } oss << " }"; return oss.str(); } } } // end namespace Catch #endif // TWOBLUECUBES_CATCH_TOSTRING_H_INCLUDED catch-1.12.1/include/internal/catch_tostring.hpp000066400000000000000000000132361325474075300216600ustar00rootroot00000000000000/* * Created by Phil on 23/4/2014. * Copyright 2014 Two Blue Cubes Ltd. All rights reserved. * * Distributed under the Boost Software License, Version 1.0. (See accompanying * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) */ #ifndef TWOBLUECUBES_CATCH_TOSTRING_HPP_INCLUDED #define TWOBLUECUBES_CATCH_TOSTRING_HPP_INCLUDED #include "catch_tostring.h" #include "catch_interfaces_config.h" namespace Catch { namespace Detail { const std::string unprintableString = "{?}"; namespace { const int hexThreshold = 255; struct Endianness { enum Arch { Big, Little }; static Arch which() { union _{ int asInt; char asChar[sizeof (int)]; } u; u.asInt = 1; return ( u.asChar[sizeof(int)-1] == 1 ) ? Big : Little; } }; } std::string rawMemoryToString( const void *object, std::size_t size ) { // Reverse order for little endian architectures int i = 0, end = static_cast( size ), inc = 1; if( Endianness::which() == Endianness::Little ) { i = end-1; end = inc = -1; } unsigned char const *bytes = static_cast(object); std::ostringstream os; os << "0x" << std::setfill('0') << std::hex; for( ; i != end; i += inc ) os << std::setw(2) << static_cast(bytes[i]); return os.str(); } } std::string toString( std::string const& value ) { std::string s = value; if( getCurrentContext().getConfig()->showInvisibles() ) { for(size_t i = 0; i < s.size(); ++i ) { std::string subs; switch( s[i] ) { case '\n': subs = "\\n"; break; case '\t': subs = "\\t"; break; default: break; } if( !subs.empty() ) { s = s.substr( 0, i ) + subs + s.substr( i+1 ); ++i; } } } return '"' + s + '"'; } std::string toString( std::wstring const& value ) { std::string s; s.reserve( value.size() ); for(size_t i = 0; i < value.size(); ++i ) s += value[i] <= 0xff ? static_cast( value[i] ) : '?'; return Catch::toString( s ); } std::string toString( const char* const value ) { return value ? Catch::toString( std::string( value ) ) : std::string( "{null string}" ); } std::string toString( char* const value ) { return Catch::toString( static_cast( value ) ); } std::string toString( const wchar_t* const value ) { return value ? Catch::toString( std::wstring(value) ) : std::string( "{null string}" ); } std::string toString( wchar_t* const value ) { return Catch::toString( static_cast( value ) ); } std::string toString( int value ) { std::ostringstream oss; oss << value; if( value > Detail::hexThreshold ) oss << " (0x" << std::hex << value << ')'; return oss.str(); } std::string toString( unsigned long value ) { std::ostringstream oss; oss << value; if( value > Detail::hexThreshold ) oss << " (0x" << std::hex << value << ')'; return oss.str(); } std::string toString( unsigned int value ) { return Catch::toString( static_cast( value ) ); } template std::string fpToString( T value, int precision ) { std::ostringstream oss; oss << std::setprecision( precision ) << std::fixed << value; std::string d = oss.str(); std::size_t i = d.find_last_not_of( '0' ); if( i != std::string::npos && i != d.size()-1 ) { if( d[i] == '.' ) i++; d = d.substr( 0, i+1 ); } return d; } std::string toString( const double value ) { return fpToString( value, 10 ); } std::string toString( const float value ) { return fpToString( value, 5 ) + 'f'; } std::string toString( bool value ) { return value ? "true" : "false"; } std::string toString( char value ) { if ( value == '\r' ) return "'\\r'"; if ( value == '\f' ) return "'\\f'"; if ( value == '\n' ) return "'\\n'"; if ( value == '\t' ) return "'\\t'"; if ( '\0' <= value && value < ' ' ) return toString( static_cast( value ) ); char chstr[] = "' '"; chstr[1] = value; return chstr; } std::string toString( signed char value ) { return toString( static_cast( value ) ); } std::string toString( unsigned char value ) { return toString( static_cast( value ) ); } #ifdef CATCH_CONFIG_CPP11_LONG_LONG std::string toString( long long value ) { std::ostringstream oss; oss << value; if( value > Detail::hexThreshold ) oss << " (0x" << std::hex << value << ')'; return oss.str(); } std::string toString( unsigned long long value ) { std::ostringstream oss; oss << value; if( value > Detail::hexThreshold ) oss << " (0x" << std::hex << value << ')'; return oss.str(); } #endif #ifdef CATCH_CONFIG_CPP11_NULLPTR std::string toString( std::nullptr_t ) { return "nullptr"; } #endif #ifdef __OBJC__ std::string toString( NSString const * const& nsstring ) { if( !nsstring ) return "nil"; return "@" + toString([nsstring UTF8String]); } std::string toString( NSString * CATCH_ARC_STRONG & nsstring ) { if( !nsstring ) return "nil"; return "@" + toString([nsstring UTF8String]); } std::string toString( NSObject* const& nsObject ) { return toString( [nsObject description] ); } #endif } // end namespace Catch #endif // TWOBLUECUBES_CATCH_TOSTRING_HPP_INCLUDED catch-1.12.1/include/internal/catch_totals.hpp000066400000000000000000000043361325474075300213160ustar00rootroot00000000000000/* * Created by Phil Nash on 23/02/2012. * Copyright (c) 2012 Two Blue Cubes Ltd. All rights reserved. * * Distributed under the Boost Software License, Version 1.0. (See accompanying * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) */ #ifndef TWOBLUECUBES_CATCH_TOTALS_HPP_INCLUDED #define TWOBLUECUBES_CATCH_TOTALS_HPP_INCLUDED #include namespace Catch { struct Counts { Counts() : passed( 0 ), failed( 0 ), failedButOk( 0 ) {} Counts operator - ( Counts const& other ) const { Counts diff; diff.passed = passed - other.passed; diff.failed = failed - other.failed; diff.failedButOk = failedButOk - other.failedButOk; return diff; } Counts& operator += ( Counts const& other ) { passed += other.passed; failed += other.failed; failedButOk += other.failedButOk; return *this; } std::size_t total() const { return passed + failed + failedButOk; } bool allPassed() const { return failed == 0 && failedButOk == 0; } bool allOk() const { return failed == 0; } std::size_t passed; std::size_t failed; std::size_t failedButOk; }; struct Totals { Totals operator - ( Totals const& other ) const { Totals diff; diff.assertions = assertions - other.assertions; diff.testCases = testCases - other.testCases; return diff; } Totals delta( Totals const& prevTotals ) const { Totals diff = *this - prevTotals; if( diff.assertions.failed > 0 ) ++diff.testCases.failed; else if( diff.assertions.failedButOk > 0 ) ++diff.testCases.failedButOk; else ++diff.testCases.passed; return diff; } Totals& operator += ( Totals const& other ) { assertions += other.assertions; testCases += other.testCases; return *this; } Counts assertions; Counts testCases; }; } #endif // TWOBLUECUBES_CATCH_TOTALS_HPP_INCLUDED catch-1.12.1/include/internal/catch_type_traits.hpp000066400000000000000000000021041325474075300223460ustar00rootroot00000000000000/* * Created by Martin on 08/02/2017. * * Distributed under the Boost Software License, Version 1.0. (See accompanying * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) */ #ifndef TWOBLUECUBES_CATCH_TYPE_TRAITS_HPP_INCLUDED #define TWOBLUECUBES_CATCH_TYPE_TRAITS_HPP_INCLUDED #if defined(CATCH_CONFIG_CPP11_TYPE_TRAITS) #include #endif namespace Catch { #if defined(CATCH_CONFIG_CPP11_TYPE_TRAITS) template using add_lvalue_reference = std::add_lvalue_reference; template using add_const = std::add_const; #else template struct add_const { typedef const T type; }; template struct add_lvalue_reference { typedef T& type; }; template struct add_lvalue_reference { typedef T& type; }; // No && overload, because that is C++11, in which case we have // proper type_traits implementation from the standard library #endif } #endif // TWOBLUECUBES_CATCH_TYPE_TRAITS_HPP_INCLUDED catch-1.12.1/include/internal/catch_version.h000066400000000000000000000022241325474075300211270ustar00rootroot00000000000000/* * Created by Phil on 13/11/2012. * Copyright 2012 Two Blue Cubes Ltd. All rights reserved. * * Distributed under the Boost Software License, Version 1.0. (See accompanying * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) */ #ifndef TWOBLUECUBES_CATCH_VERSION_H_INCLUDED #define TWOBLUECUBES_CATCH_VERSION_H_INCLUDED namespace Catch { // Versioning information struct Version { Version( unsigned int _majorVersion, unsigned int _minorVersion, unsigned int _patchNumber, char const * const _branchName, unsigned int _buildNumber ); unsigned int const majorVersion; unsigned int const minorVersion; unsigned int const patchNumber; // buildNumber is only used if branchName is not null char const * const branchName; unsigned int const buildNumber; friend std::ostream& operator << ( std::ostream& os, Version const& version ); private: void operator=( Version const& ); }; inline Version libraryVersion(); } #endif // TWOBLUECUBES_CATCH_VERSION_H_INCLUDED catch-1.12.1/include/internal/catch_version.hpp000066400000000000000000000026221325474075300214710ustar00rootroot00000000000000/* * Created by Phil on 14/11/2012. * Copyright 2012 Two Blue Cubes Ltd. All rights reserved. * * Distributed under the Boost Software License, Version 1.0. (See accompanying * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) */ #ifndef TWOBLUECUBES_CATCH_VERSION_HPP_INCLUDED #define TWOBLUECUBES_CATCH_VERSION_HPP_INCLUDED #include "catch_version.h" namespace Catch { Version::Version ( unsigned int _majorVersion, unsigned int _minorVersion, unsigned int _patchNumber, char const * const _branchName, unsigned int _buildNumber ) : majorVersion( _majorVersion ), minorVersion( _minorVersion ), patchNumber( _patchNumber ), branchName( _branchName ), buildNumber( _buildNumber ) {} std::ostream& operator << ( std::ostream& os, Version const& version ) { os << version.majorVersion << '.' << version.minorVersion << '.' << version.patchNumber; // branchName is never null -> 0th char is \0 if it is empty if (version.branchName[0]) { os << '-' << version.branchName << '.' << version.buildNumber; } return os; } inline Version libraryVersion() { static Version version( 1, 12, 1, "", 0 ); return version; } } #endif // TWOBLUECUBES_CATCH_VERSION_HPP_INCLUDED catch-1.12.1/include/internal/catch_wildcard_pattern.hpp000066400000000000000000000046341325474075300233370ustar00rootroot00000000000000/* * Created by Phil on 13/7/2015. * Copyright 2015 Two Blue Cubes Ltd. All rights reserved. * * Distributed under the Boost Software License, Version 1.0. (See accompanying * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) */ #ifndef TWOBLUECUBES_CATCH_WILDCARD_PATTERN_HPP_INCLUDED #define TWOBLUECUBES_CATCH_WILDCARD_PATTERN_HPP_INCLUDED #include "catch_common.h" #include namespace Catch { class WildcardPattern { enum WildcardPosition { NoWildcard = 0, WildcardAtStart = 1, WildcardAtEnd = 2, WildcardAtBothEnds = WildcardAtStart | WildcardAtEnd }; public: WildcardPattern( std::string const& pattern, CaseSensitive::Choice caseSensitivity ) : m_caseSensitivity( caseSensitivity ), m_wildcard( NoWildcard ), m_pattern( adjustCase( pattern ) ) { if( startsWith( m_pattern, '*' ) ) { m_pattern = m_pattern.substr( 1 ); m_wildcard = WildcardAtStart; } if( endsWith( m_pattern, '*' ) ) { m_pattern = m_pattern.substr( 0, m_pattern.size()-1 ); m_wildcard = static_cast( m_wildcard | WildcardAtEnd ); } } virtual ~WildcardPattern(); virtual bool matches( std::string const& str ) const { switch( m_wildcard ) { case NoWildcard: return m_pattern == adjustCase( str ); case WildcardAtStart: return endsWith( adjustCase( str ), m_pattern ); case WildcardAtEnd: return startsWith( adjustCase( str ), m_pattern ); case WildcardAtBothEnds: return contains( adjustCase( str ), m_pattern ); } #ifdef __clang__ #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wunreachable-code" #endif throw std::logic_error( "Unknown enum" ); #ifdef __clang__ #pragma clang diagnostic pop #endif } private: std::string adjustCase( std::string const& str ) const { return m_caseSensitivity == CaseSensitive::No ? toLower( str ) : str; } CaseSensitive::Choice m_caseSensitivity; WildcardPosition m_wildcard; std::string m_pattern; }; } #endif // TWOBLUECUBES_CATCH_WILDCARD_PATTERN_HPP_INCLUDED catch-1.12.1/include/internal/catch_windows_h_proxy.h000066400000000000000000000013041325474075300227020ustar00rootroot00000000000000/* * Created by Martin on 16/01/2017. * * Distributed under the Boost Software License, Version 1.0. (See accompanying * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) */ #ifndef TWOBLUECUBES_CATCH_WINDOWS_H_PROXY_H_INCLUDED #define TWOBLUECUBES_CATCH_WINDOWS_H_PROXY_H_INCLUDED #ifdef CATCH_DEFINES_NOMINMAX # define NOMINMAX #endif #ifdef CATCH_DEFINES_WIN32_LEAN_AND_MEAN # define WIN32_LEAN_AND_MEAN #endif #ifdef __AFXDLL #include #else #include #endif #ifdef CATCH_DEFINES_NOMINMAX # undef NOMINMAX #endif #ifdef CATCH_DEFINES_WIN32_LEAN_AND_MEAN # undef WIN32_LEAN_AND_MEAN #endif #endif // TWOBLUECUBES_CATCH_WINDOWS_H_PROXY_H_INCLUDED catch-1.12.1/include/internal/catch_xmlwriter.hpp000066400000000000000000000163771325474075300220550ustar00rootroot00000000000000/* * Created by Phil on 09/12/2010. * Copyright 2010 Two Blue Cubes Ltd. All rights reserved. * * Distributed under the Boost Software License, Version 1.0. (See accompanying * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) */ #ifndef TWOBLUECUBES_CATCH_XMLWRITER_HPP_INCLUDED #define TWOBLUECUBES_CATCH_XMLWRITER_HPP_INCLUDED #include "catch_stream.h" #include "catch_compiler_capabilities.h" #include #include #include #include namespace Catch { class XmlEncode { public: enum ForWhat { ForTextNodes, ForAttributes }; XmlEncode( std::string const& str, ForWhat forWhat = ForTextNodes ) : m_str( str ), m_forWhat( forWhat ) {} void encodeTo( std::ostream& os ) const { // Apostrophe escaping not necessary if we always use " to write attributes // (see: http://www.w3.org/TR/xml/#syntax) for( std::size_t i = 0; i < m_str.size(); ++ i ) { char c = m_str[i]; switch( c ) { case '<': os << "<"; break; case '&': os << "&"; break; case '>': // See: http://www.w3.org/TR/xml/#syntax if( i > 2 && m_str[i-1] == ']' && m_str[i-2] == ']' ) os << ">"; else os << c; break; case '\"': if( m_forWhat == ForAttributes ) os << """; else os << c; break; default: // Escape control chars - based on contribution by @espenalb in PR #465 and // by @mrpi PR #588 if ( ( c >= 0 && c < '\x09' ) || ( c > '\x0D' && c < '\x20') || c=='\x7F' ) { // see http://stackoverflow.com/questions/404107/why-are-control-characters-illegal-in-xml-1-0 os << "\\x" << std::uppercase << std::hex << std::setfill('0') << std::setw(2) << static_cast( c ); } else os << c; } } } friend std::ostream& operator << ( std::ostream& os, XmlEncode const& xmlEncode ) { xmlEncode.encodeTo( os ); return os; } private: std::string m_str; ForWhat m_forWhat; }; class XmlWriter { public: class ScopedElement { public: ScopedElement( XmlWriter* writer ) : m_writer( writer ) {} ScopedElement( ScopedElement const& other ) : m_writer( other.m_writer ){ other.m_writer = CATCH_NULL; } ~ScopedElement() { if( m_writer ) m_writer->endElement(); } ScopedElement& writeText( std::string const& text, bool indent = true ) { m_writer->writeText( text, indent ); return *this; } template ScopedElement& writeAttribute( std::string const& name, T const& attribute ) { m_writer->writeAttribute( name, attribute ); return *this; } private: mutable XmlWriter* m_writer; }; XmlWriter() : m_tagIsOpen( false ), m_needsNewline( false ), m_os( Catch::cout() ) { writeDeclaration(); } XmlWriter( std::ostream& os ) : m_tagIsOpen( false ), m_needsNewline( false ), m_os( os ) { writeDeclaration(); } ~XmlWriter() { while( !m_tags.empty() ) endElement(); } XmlWriter& startElement( std::string const& name ) { ensureTagClosed(); newlineIfNecessary(); m_os << m_indent << '<' << name; m_tags.push_back( name ); m_indent += " "; m_tagIsOpen = true; return *this; } ScopedElement scopedElement( std::string const& name ) { ScopedElement scoped( this ); startElement( name ); return scoped; } XmlWriter& endElement() { newlineIfNecessary(); m_indent = m_indent.substr( 0, m_indent.size()-2 ); if( m_tagIsOpen ) { m_os << "/>"; m_tagIsOpen = false; } else { m_os << m_indent << ""; } m_os << std::endl; m_tags.pop_back(); return *this; } XmlWriter& writeAttribute( std::string const& name, std::string const& attribute ) { if( !name.empty() && !attribute.empty() ) m_os << ' ' << name << "=\"" << XmlEncode( attribute, XmlEncode::ForAttributes ) << '"'; return *this; } XmlWriter& writeAttribute( std::string const& name, bool attribute ) { m_os << ' ' << name << "=\"" << ( attribute ? "true" : "false" ) << '"'; return *this; } template XmlWriter& writeAttribute( std::string const& name, T const& attribute ) { std::ostringstream oss; oss << attribute; return writeAttribute( name, oss.str() ); } XmlWriter& writeText( std::string const& text, bool indent = true ) { if( !text.empty() ){ bool tagWasOpen = m_tagIsOpen; ensureTagClosed(); if( tagWasOpen && indent ) m_os << m_indent; m_os << XmlEncode( text ); m_needsNewline = true; } return *this; } XmlWriter& writeComment( std::string const& text ) { ensureTagClosed(); m_os << m_indent << ""; m_needsNewline = true; return *this; } void writeStylesheetRef( std::string const& url ) { m_os << "\n"; } XmlWriter& writeBlankLine() { ensureTagClosed(); m_os << '\n'; return *this; } void ensureTagClosed() { if( m_tagIsOpen ) { m_os << ">" << std::endl; m_tagIsOpen = false; } } private: XmlWriter( XmlWriter const& ); void operator=( XmlWriter const& ); void writeDeclaration() { m_os << "\n"; } void newlineIfNecessary() { if( m_needsNewline ) { m_os << std::endl; m_needsNewline = false; } } bool m_tagIsOpen; bool m_needsNewline; std::vector m_tags; std::string m_indent; std::ostream& m_os; }; } #endif // TWOBLUECUBES_CATCH_XMLWRITER_HPP_INCLUDED catch-1.12.1/include/reporters/000077500000000000000000000000001325474075300163405ustar00rootroot00000000000000catch-1.12.1/include/reporters/catch_reporter_automake.hpp000066400000000000000000000043141325474075300237450ustar00rootroot00000000000000/* * Created by Justin R. Wilson on 2/19/2017. * Copyright 2017 Justin R. Wilson. All rights reserved. * * Distributed under the Boost Software License, Version 1.0. (See accompanying * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) */ #ifndef TWOBLUECUBES_CATCH_REPORTER_AUTOMAKE_HPP_INCLUDED #define TWOBLUECUBES_CATCH_REPORTER_AUTOMAKE_HPP_INCLUDED // Don't #include any Catch headers here - we can assume they are already // included before this header. // This is not good practice in general but is necessary in this case so this // file can be distributed as a single header that works with the main // Catch single header. namespace Catch { struct AutomakeReporter : StreamingReporterBase { AutomakeReporter( ReporterConfig const& _config ) : StreamingReporterBase( _config ) {} virtual ~AutomakeReporter(); static std::string getDescription() { return "Reports test results in the format of Automake .trs files"; } virtual void assertionStarting( AssertionInfo const& ) CATCH_OVERRIDE {} virtual bool assertionEnded( AssertionStats const& /*_assertionStats*/ ) CATCH_OVERRIDE { return true; } virtual void testCaseEnded( TestCaseStats const& _testCaseStats ) CATCH_OVERRIDE { // Possible values to emit are PASS, XFAIL, SKIP, FAIL, XPASS and ERROR. stream << ":test-result: "; if (_testCaseStats.totals.assertions.allPassed()) { stream << "PASS"; } else if (_testCaseStats.totals.assertions.allOk()) { stream << "XFAIL"; } else { stream << "FAIL"; } stream << ' ' << _testCaseStats.testInfo.name << '\n'; StreamingReporterBase::testCaseEnded( _testCaseStats ); } virtual void skipTest( TestCaseInfo const& testInfo ) CATCH_OVERRIDE { stream << ":test-result: SKIP " << testInfo.name << '\n'; } }; #ifdef CATCH_IMPL AutomakeReporter::~AutomakeReporter() {} #endif INTERNAL_CATCH_REGISTER_REPORTER( "automake", AutomakeReporter) } // end namespace Catch #endif // TWOBLUECUBES_CATCH_REPORTER_AUTOMAKE_HPP_INCLUDED catch-1.12.1/include/reporters/catch_reporter_bases.hpp000066400000000000000000000260021325474075300232320ustar00rootroot00000000000000/* * Created by Phil on 27/11/2013. * Copyright 2013 Two Blue Cubes Ltd. All rights reserved. * * Distributed under the Boost Software License, Version 1.0. (See accompanying * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) */ #ifndef TWOBLUECUBES_CATCH_REPORTER_BASES_HPP_INCLUDED #define TWOBLUECUBES_CATCH_REPORTER_BASES_HPP_INCLUDED #include "../internal/catch_interfaces_reporter.h" #include "../internal/catch_errno_guard.hpp" #include #include #include #include namespace Catch { namespace { // Because formatting using c++ streams is stateful, drop down to C is required // Alternatively we could use stringstream, but its performance is... not good. std::string getFormattedDuration( double duration ) { // Max exponent + 1 is required to represent the whole part // + 1 for decimal point // + 3 for the 3 decimal places // + 1 for null terminator const size_t maxDoubleSize = DBL_MAX_10_EXP + 1 + 1 + 3 + 1; char buffer[maxDoubleSize]; // Save previous errno, to prevent sprintf from overwriting it ErrnoGuard guard; #ifdef _MSC_VER sprintf_s(buffer, "%.3f", duration); #else sprintf(buffer, "%.3f", duration); #endif return std::string(buffer); } } struct StreamingReporterBase : SharedImpl { StreamingReporterBase( ReporterConfig const& _config ) : m_config( _config.fullConfig() ), stream( _config.stream() ) { m_reporterPrefs.shouldRedirectStdOut = false; } virtual ReporterPreferences getPreferences() const CATCH_OVERRIDE { return m_reporterPrefs; } virtual ~StreamingReporterBase() CATCH_OVERRIDE; virtual void noMatchingTestCases( std::string const& ) CATCH_OVERRIDE {} virtual void testRunStarting( TestRunInfo const& _testRunInfo ) CATCH_OVERRIDE { currentTestRunInfo = _testRunInfo; } virtual void testGroupStarting( GroupInfo const& _groupInfo ) CATCH_OVERRIDE { currentGroupInfo = _groupInfo; } virtual void testCaseStarting( TestCaseInfo const& _testInfo ) CATCH_OVERRIDE { currentTestCaseInfo = _testInfo; } virtual void sectionStarting( SectionInfo const& _sectionInfo ) CATCH_OVERRIDE { m_sectionStack.push_back( _sectionInfo ); } virtual void sectionEnded( SectionStats const& /* _sectionStats */ ) CATCH_OVERRIDE { m_sectionStack.pop_back(); } virtual void testCaseEnded( TestCaseStats const& /* _testCaseStats */ ) CATCH_OVERRIDE { currentTestCaseInfo.reset(); } virtual void testGroupEnded( TestGroupStats const& /* _testGroupStats */ ) CATCH_OVERRIDE { currentGroupInfo.reset(); } virtual void testRunEnded( TestRunStats const& /* _testRunStats */ ) CATCH_OVERRIDE { currentTestCaseInfo.reset(); currentGroupInfo.reset(); currentTestRunInfo.reset(); } virtual void skipTest( TestCaseInfo const& ) CATCH_OVERRIDE { // Don't do anything with this by default. // It can optionally be overridden in the derived class. } Ptr m_config; std::ostream& stream; LazyStat currentTestRunInfo; LazyStat currentGroupInfo; LazyStat currentTestCaseInfo; std::vector m_sectionStack; ReporterPreferences m_reporterPrefs; }; struct CumulativeReporterBase : SharedImpl { template struct Node : SharedImpl<> { explicit Node( T const& _value ) : value( _value ) {} virtual ~Node() {} typedef std::vector > ChildNodes; T value; ChildNodes children; }; struct SectionNode : SharedImpl<> { explicit SectionNode( SectionStats const& _stats ) : stats( _stats ) {} virtual ~SectionNode(); bool operator == ( SectionNode const& other ) const { return stats.sectionInfo.lineInfo == other.stats.sectionInfo.lineInfo; } bool operator == ( Ptr const& other ) const { return operator==( *other ); } SectionStats stats; typedef std::vector > ChildSections; typedef std::vector Assertions; ChildSections childSections; Assertions assertions; std::string stdOut; std::string stdErr; }; struct BySectionInfo { BySectionInfo( SectionInfo const& other ) : m_other( other ) {} BySectionInfo( BySectionInfo const& other ) : m_other( other.m_other ) {} bool operator() ( Ptr const& node ) const { return ((node->stats.sectionInfo.name == m_other.name) && (node->stats.sectionInfo.lineInfo == m_other.lineInfo)); } private: void operator=( BySectionInfo const& ); SectionInfo const& m_other; }; typedef Node TestCaseNode; typedef Node TestGroupNode; typedef Node TestRunNode; CumulativeReporterBase( ReporterConfig const& _config ) : m_config( _config.fullConfig() ), stream( _config.stream() ) { m_reporterPrefs.shouldRedirectStdOut = false; } ~CumulativeReporterBase(); virtual ReporterPreferences getPreferences() const CATCH_OVERRIDE { return m_reporterPrefs; } virtual void testRunStarting( TestRunInfo const& ) CATCH_OVERRIDE {} virtual void testGroupStarting( GroupInfo const& ) CATCH_OVERRIDE {} virtual void testCaseStarting( TestCaseInfo const& ) CATCH_OVERRIDE {} virtual void sectionStarting( SectionInfo const& sectionInfo ) CATCH_OVERRIDE { SectionStats incompleteStats( sectionInfo, Counts(), 0, false ); Ptr node; if( m_sectionStack.empty() ) { if( !m_rootSection ) m_rootSection = new SectionNode( incompleteStats ); node = m_rootSection; } else { SectionNode& parentNode = *m_sectionStack.back(); SectionNode::ChildSections::const_iterator it = std::find_if( parentNode.childSections.begin(), parentNode.childSections.end(), BySectionInfo( sectionInfo ) ); if( it == parentNode.childSections.end() ) { node = new SectionNode( incompleteStats ); parentNode.childSections.push_back( node ); } else node = *it; } m_sectionStack.push_back( node ); m_deepestSection = node; } virtual void assertionStarting( AssertionInfo const& ) CATCH_OVERRIDE {} virtual bool assertionEnded( AssertionStats const& assertionStats ) CATCH_OVERRIDE { assert( !m_sectionStack.empty() ); SectionNode& sectionNode = *m_sectionStack.back(); sectionNode.assertions.push_back( assertionStats ); // AssertionResult holds a pointer to a temporary DecomposedExpression, // which getExpandedExpression() calls to build the expression string. // Our section stack copy of the assertionResult will likely outlive the // temporary, so it must be expanded or discarded now to avoid calling // a destroyed object later. prepareExpandedExpression( sectionNode.assertions.back().assertionResult ); return true; } virtual void sectionEnded( SectionStats const& sectionStats ) CATCH_OVERRIDE { assert( !m_sectionStack.empty() ); SectionNode& node = *m_sectionStack.back(); node.stats = sectionStats; m_sectionStack.pop_back(); } virtual void testCaseEnded( TestCaseStats const& testCaseStats ) CATCH_OVERRIDE { Ptr node = new TestCaseNode( testCaseStats ); assert( m_sectionStack.size() == 0 ); node->children.push_back( m_rootSection ); m_testCases.push_back( node ); m_rootSection.reset(); assert( m_deepestSection ); m_deepestSection->stdOut = testCaseStats.stdOut; m_deepestSection->stdErr = testCaseStats.stdErr; } virtual void testGroupEnded( TestGroupStats const& testGroupStats ) CATCH_OVERRIDE { Ptr node = new TestGroupNode( testGroupStats ); node->children.swap( m_testCases ); m_testGroups.push_back( node ); } virtual void testRunEnded( TestRunStats const& testRunStats ) CATCH_OVERRIDE { Ptr node = new TestRunNode( testRunStats ); node->children.swap( m_testGroups ); m_testRuns.push_back( node ); testRunEndedCumulative(); } virtual void testRunEndedCumulative() = 0; virtual void skipTest( TestCaseInfo const& ) CATCH_OVERRIDE {} virtual void prepareExpandedExpression( AssertionResult& result ) const { if( result.isOk() ) result.discardDecomposedExpression(); else result.expandDecomposedExpression(); } Ptr m_config; std::ostream& stream; std::vector m_assertions; std::vector > > m_sections; std::vector > m_testCases; std::vector > m_testGroups; std::vector > m_testRuns; Ptr m_rootSection; Ptr m_deepestSection; std::vector > m_sectionStack; ReporterPreferences m_reporterPrefs; }; template char const* getLineOfChars() { static char line[CATCH_CONFIG_CONSOLE_WIDTH] = {0}; if( !*line ) { std::memset( line, C, CATCH_CONFIG_CONSOLE_WIDTH-1 ); line[CATCH_CONFIG_CONSOLE_WIDTH-1] = 0; } return line; } struct TestEventListenerBase : StreamingReporterBase { TestEventListenerBase( ReporterConfig const& _config ) : StreamingReporterBase( _config ) {} virtual void assertionStarting( AssertionInfo const& ) CATCH_OVERRIDE {} virtual bool assertionEnded( AssertionStats const& ) CATCH_OVERRIDE { return false; } }; } // end namespace Catch #endif // TWOBLUECUBES_CATCH_REPORTER_BASES_HPP_INCLUDED catch-1.12.1/include/reporters/catch_reporter_compact.hpp000066400000000000000000000303111325474075300235610ustar00rootroot00000000000000/* * Created by Martin Moene on 2013-12-05. * Copyright 2012 Martin Moene. All rights reserved. * * Distributed under the Boost Software License, Version 1.0. (See accompanying * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) */ #ifndef TWOBLUECUBES_CATCH_REPORTER_COMPACT_HPP_INCLUDED #define TWOBLUECUBES_CATCH_REPORTER_COMPACT_HPP_INCLUDED #include "catch_reporter_bases.hpp" #include "../internal/catch_reporter_registrars.hpp" #include "../internal/catch_console_colour.hpp" namespace Catch { struct CompactReporter : StreamingReporterBase { CompactReporter( ReporterConfig const& _config ) : StreamingReporterBase( _config ) {} virtual ~CompactReporter(); static std::string getDescription() { return "Reports test results on a single line, suitable for IDEs"; } virtual ReporterPreferences getPreferences() const { ReporterPreferences prefs; prefs.shouldRedirectStdOut = false; return prefs; } virtual void noMatchingTestCases( std::string const& spec ) { stream << "No test cases matched '" << spec << '\'' << std::endl; } virtual void assertionStarting( AssertionInfo const& ) {} virtual bool assertionEnded( AssertionStats const& _assertionStats ) { AssertionResult const& result = _assertionStats.assertionResult; bool printInfoMessages = true; // Drop out if result was successful and we're not printing those if( !m_config->includeSuccessfulResults() && result.isOk() ) { if( result.getResultType() != ResultWas::Warning ) return false; printInfoMessages = false; } AssertionPrinter printer( stream, _assertionStats, printInfoMessages ); printer.print(); stream << std::endl; return true; } virtual void sectionEnded(SectionStats const& _sectionStats) CATCH_OVERRIDE { if (m_config->showDurations() == ShowDurations::Always) { stream << getFormattedDuration(_sectionStats.durationInSeconds) << " s: " << _sectionStats.sectionInfo.name << std::endl; } } virtual void testRunEnded( TestRunStats const& _testRunStats ) { printTotals( _testRunStats.totals ); stream << '\n' << std::endl; StreamingReporterBase::testRunEnded( _testRunStats ); } private: class AssertionPrinter { void operator= ( AssertionPrinter const& ); public: AssertionPrinter( std::ostream& _stream, AssertionStats const& _stats, bool _printInfoMessages ) : stream( _stream ) , stats( _stats ) , result( _stats.assertionResult ) , messages( _stats.infoMessages ) , itMessage( _stats.infoMessages.begin() ) , printInfoMessages( _printInfoMessages ) {} void print() { printSourceInfo(); itMessage = messages.begin(); switch( result.getResultType() ) { case ResultWas::Ok: printResultType( Colour::ResultSuccess, passedString() ); printOriginalExpression(); printReconstructedExpression(); if ( ! result.hasExpression() ) printRemainingMessages( Colour::None ); else printRemainingMessages(); break; case ResultWas::ExpressionFailed: if( result.isOk() ) printResultType( Colour::ResultSuccess, failedString() + std::string( " - but was ok" ) ); else printResultType( Colour::Error, failedString() ); printOriginalExpression(); printReconstructedExpression(); printRemainingMessages(); break; case ResultWas::ThrewException: printResultType( Colour::Error, failedString() ); printIssue( "unexpected exception with message:" ); printMessage(); printExpressionWas(); printRemainingMessages(); break; case ResultWas::FatalErrorCondition: printResultType( Colour::Error, failedString() ); printIssue( "fatal error condition with message:" ); printMessage(); printExpressionWas(); printRemainingMessages(); break; case ResultWas::DidntThrowException: printResultType( Colour::Error, failedString() ); printIssue( "expected exception, got none" ); printExpressionWas(); printRemainingMessages(); break; case ResultWas::Info: printResultType( Colour::None, "info" ); printMessage(); printRemainingMessages(); break; case ResultWas::Warning: printResultType( Colour::None, "warning" ); printMessage(); printRemainingMessages(); break; case ResultWas::ExplicitFailure: printResultType( Colour::Error, failedString() ); printIssue( "explicitly" ); printRemainingMessages( Colour::None ); break; // These cases are here to prevent compiler warnings case ResultWas::Unknown: case ResultWas::FailureBit: case ResultWas::Exception: printResultType( Colour::Error, "** internal error **" ); break; } } private: // Colour::LightGrey static Colour::Code dimColour() { return Colour::FileName; } #ifdef CATCH_PLATFORM_MAC static const char* failedString() { return "FAILED"; } static const char* passedString() { return "PASSED"; } #else static const char* failedString() { return "failed"; } static const char* passedString() { return "passed"; } #endif void printSourceInfo() const { Colour colourGuard( Colour::FileName ); stream << result.getSourceInfo() << ':'; } void printResultType( Colour::Code colour, std::string const& passOrFail ) const { if( !passOrFail.empty() ) { { Colour colourGuard( colour ); stream << ' ' << passOrFail; } stream << ':'; } } void printIssue( std::string const& issue ) const { stream << ' ' << issue; } void printExpressionWas() { if( result.hasExpression() ) { stream << ';'; { Colour colour( dimColour() ); stream << " expression was:"; } printOriginalExpression(); } } void printOriginalExpression() const { if( result.hasExpression() ) { stream << ' ' << result.getExpression(); } } void printReconstructedExpression() const { if( result.hasExpandedExpression() ) { { Colour colour( dimColour() ); stream << " for: "; } stream << result.getExpandedExpression(); } } void printMessage() { if ( itMessage != messages.end() ) { stream << " '" << itMessage->message << '\''; ++itMessage; } } void printRemainingMessages( Colour::Code colour = dimColour() ) { if ( itMessage == messages.end() ) return; // using messages.end() directly yields compilation error: std::vector::const_iterator itEnd = messages.end(); const std::size_t N = static_cast( std::distance( itMessage, itEnd ) ); { Colour colourGuard( colour ); stream << " with " << pluralise( N, "message" ) << ':'; } for(; itMessage != itEnd; ) { // If this assertion is a warning ignore any INFO messages if( printInfoMessages || itMessage->type != ResultWas::Info ) { stream << " '" << itMessage->message << '\''; if ( ++itMessage != itEnd ) { Colour colourGuard( dimColour() ); stream << " and"; } } } } private: std::ostream& stream; AssertionStats const& stats; AssertionResult const& result; std::vector messages; std::vector::const_iterator itMessage; bool printInfoMessages; }; // Colour, message variants: // - white: No tests ran. // - red: Failed [both/all] N test cases, failed [both/all] M assertions. // - white: Passed [both/all] N test cases (no assertions). // - red: Failed N tests cases, failed M assertions. // - green: Passed [both/all] N tests cases with M assertions. std::string bothOrAll( std::size_t count ) const { return count == 1 ? std::string() : count == 2 ? "both " : "all " ; } void printTotals( const Totals& totals ) const { if( totals.testCases.total() == 0 ) { stream << "No tests ran."; } else if( totals.testCases.failed == totals.testCases.total() ) { Colour colour( Colour::ResultError ); const std::string qualify_assertions_failed = totals.assertions.failed == totals.assertions.total() ? bothOrAll( totals.assertions.failed ) : std::string(); stream << "Failed " << bothOrAll( totals.testCases.failed ) << pluralise( totals.testCases.failed, "test case" ) << ", " "failed " << qualify_assertions_failed << pluralise( totals.assertions.failed, "assertion" ) << '.'; } else if( totals.assertions.total() == 0 ) { stream << "Passed " << bothOrAll( totals.testCases.total() ) << pluralise( totals.testCases.total(), "test case" ) << " (no assertions)."; } else if( totals.assertions.failed ) { Colour colour( Colour::ResultError ); stream << "Failed " << pluralise( totals.testCases.failed, "test case" ) << ", " "failed " << pluralise( totals.assertions.failed, "assertion" ) << '.'; } else { Colour colour( Colour::ResultSuccess ); stream << "Passed " << bothOrAll( totals.testCases.passed ) << pluralise( totals.testCases.passed, "test case" ) << " with " << pluralise( totals.assertions.passed, "assertion" ) << '.'; } } }; INTERNAL_CATCH_REGISTER_REPORTER( "compact", CompactReporter ) } // end namespace Catch #endif // TWOBLUECUBES_CATCH_REPORTER_COMPACT_HPP_INCLUDED catch-1.12.1/include/reporters/catch_reporter_console.hpp000066400000000000000000000452511325474075300236060ustar00rootroot00000000000000/* * Created by Phil on 5/12/2012. * Copyright 2012 Two Blue Cubes Ltd. All rights reserved. * * Distributed under the Boost Software License, Version 1.0. (See accompanying * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) */ #ifndef TWOBLUECUBES_CATCH_REPORTER_CONSOLE_HPP_INCLUDED #define TWOBLUECUBES_CATCH_REPORTER_CONSOLE_HPP_INCLUDED #include "catch_reporter_bases.hpp" #include "../internal/catch_reporter_registrars.hpp" #include "../internal/catch_console_colour.hpp" #include #include namespace Catch { struct ConsoleReporter : StreamingReporterBase { ConsoleReporter( ReporterConfig const& _config ) : StreamingReporterBase( _config ), m_headerPrinted( false ) {} virtual ~ConsoleReporter() CATCH_OVERRIDE; static std::string getDescription() { return "Reports test results as plain lines of text"; } virtual void noMatchingTestCases( std::string const& spec ) CATCH_OVERRIDE { stream << "No test cases matched '" << spec << '\'' << std::endl; } virtual void assertionStarting( AssertionInfo const& ) CATCH_OVERRIDE { } virtual bool assertionEnded( AssertionStats const& _assertionStats ) CATCH_OVERRIDE { AssertionResult const& result = _assertionStats.assertionResult; bool includeResults = m_config->includeSuccessfulResults() || !result.isOk(); // Drop out if result was successful but we're not printing them. if( !includeResults && result.getResultType() != ResultWas::Warning ) return false; lazyPrint(); AssertionPrinter printer( stream, _assertionStats, includeResults ); printer.print(); stream << std::endl; return true; } virtual void sectionStarting( SectionInfo const& _sectionInfo ) CATCH_OVERRIDE { m_headerPrinted = false; StreamingReporterBase::sectionStarting( _sectionInfo ); } virtual void sectionEnded( SectionStats const& _sectionStats ) CATCH_OVERRIDE { if( _sectionStats.missingAssertions ) { lazyPrint(); Colour colour( Colour::ResultError ); if( m_sectionStack.size() > 1 ) stream << "\nNo assertions in section"; else stream << "\nNo assertions in test case"; stream << " '" << _sectionStats.sectionInfo.name << "'\n" << std::endl; } if( m_config->showDurations() == ShowDurations::Always ) { stream << getFormattedDuration(_sectionStats.durationInSeconds) << " s: " << _sectionStats.sectionInfo.name << std::endl; } if( m_headerPrinted ) { m_headerPrinted = false; } StreamingReporterBase::sectionEnded( _sectionStats ); } virtual void testCaseEnded( TestCaseStats const& _testCaseStats ) CATCH_OVERRIDE { StreamingReporterBase::testCaseEnded( _testCaseStats ); m_headerPrinted = false; } virtual void testGroupEnded( TestGroupStats const& _testGroupStats ) CATCH_OVERRIDE { if( currentGroupInfo.used ) { printSummaryDivider(); stream << "Summary for group '" << _testGroupStats.groupInfo.name << "':\n"; printTotals( _testGroupStats.totals ); stream << '\n' << std::endl; } StreamingReporterBase::testGroupEnded( _testGroupStats ); } virtual void testRunEnded( TestRunStats const& _testRunStats ) CATCH_OVERRIDE { printTotalsDivider( _testRunStats.totals ); printTotals( _testRunStats.totals ); stream << std::endl; StreamingReporterBase::testRunEnded( _testRunStats ); } private: class AssertionPrinter { void operator= ( AssertionPrinter const& ); public: AssertionPrinter( std::ostream& _stream, AssertionStats const& _stats, bool _printInfoMessages ) : stream( _stream ), stats( _stats ), result( _stats.assertionResult ), colour( Colour::None ), message( result.getMessage() ), messages( _stats.infoMessages ), printInfoMessages( _printInfoMessages ) { switch( result.getResultType() ) { case ResultWas::Ok: colour = Colour::Success; passOrFail = "PASSED"; //if( result.hasMessage() ) if( _stats.infoMessages.size() == 1 ) messageLabel = "with message"; if( _stats.infoMessages.size() > 1 ) messageLabel = "with messages"; break; case ResultWas::ExpressionFailed: if( result.isOk() ) { colour = Colour::Success; passOrFail = "FAILED - but was ok"; } else { colour = Colour::Error; passOrFail = "FAILED"; } if( _stats.infoMessages.size() == 1 ) messageLabel = "with message"; if( _stats.infoMessages.size() > 1 ) messageLabel = "with messages"; break; case ResultWas::ThrewException: colour = Colour::Error; passOrFail = "FAILED"; messageLabel = "due to unexpected exception with "; if (_stats.infoMessages.size() == 1) messageLabel += "message"; if (_stats.infoMessages.size() > 1) messageLabel += "messages"; break; case ResultWas::FatalErrorCondition: colour = Colour::Error; passOrFail = "FAILED"; messageLabel = "due to a fatal error condition"; break; case ResultWas::DidntThrowException: colour = Colour::Error; passOrFail = "FAILED"; messageLabel = "because no exception was thrown where one was expected"; break; case ResultWas::Info: messageLabel = "info"; break; case ResultWas::Warning: messageLabel = "warning"; break; case ResultWas::ExplicitFailure: passOrFail = "FAILED"; colour = Colour::Error; if( _stats.infoMessages.size() == 1 ) messageLabel = "explicitly with message"; if( _stats.infoMessages.size() > 1 ) messageLabel = "explicitly with messages"; break; // These cases are here to prevent compiler warnings case ResultWas::Unknown: case ResultWas::FailureBit: case ResultWas::Exception: passOrFail = "** internal error **"; colour = Colour::Error; break; } } void print() const { printSourceInfo(); if( stats.totals.assertions.total() > 0 ) { if( result.isOk() ) stream << '\n'; printResultType(); printOriginalExpression(); printReconstructedExpression(); } else { stream << '\n'; } printMessage(); } private: void printResultType() const { if( !passOrFail.empty() ) { Colour colourGuard( colour ); stream << passOrFail << ":\n"; } } void printOriginalExpression() const { if( result.hasExpression() ) { Colour colourGuard( Colour::OriginalExpression ); stream << " "; stream << result.getExpressionInMacro(); stream << '\n'; } } void printReconstructedExpression() const { if( result.hasExpandedExpression() ) { stream << "with expansion:\n"; Colour colourGuard( Colour::ReconstructedExpression ); stream << Text( result.getExpandedExpression(), TextAttributes().setIndent(2) ) << '\n'; } } void printMessage() const { if( !messageLabel.empty() ) stream << messageLabel << ':' << '\n'; for( std::vector::const_iterator it = messages.begin(), itEnd = messages.end(); it != itEnd; ++it ) { // If this assertion is a warning ignore any INFO messages if( printInfoMessages || it->type != ResultWas::Info ) stream << Text( it->message, TextAttributes().setIndent(2) ) << '\n'; } } void printSourceInfo() const { Colour colourGuard( Colour::FileName ); stream << result.getSourceInfo() << ": "; } std::ostream& stream; AssertionStats const& stats; AssertionResult const& result; Colour::Code colour; std::string passOrFail; std::string messageLabel; std::string message; std::vector messages; bool printInfoMessages; }; void lazyPrint() { if( !currentTestRunInfo.used ) lazyPrintRunInfo(); if( !currentGroupInfo.used ) lazyPrintGroupInfo(); if( !m_headerPrinted ) { printTestCaseAndSectionHeader(); m_headerPrinted = true; } } void lazyPrintRunInfo() { stream << '\n' << getLineOfChars<'~'>() << '\n'; Colour colour( Colour::SecondaryText ); stream << currentTestRunInfo->name << " is a Catch v" << libraryVersion() << " host application.\n" << "Run with -? for options\n\n"; if( m_config->rngSeed() != 0 ) stream << "Randomness seeded to: " << m_config->rngSeed() << "\n\n"; currentTestRunInfo.used = true; } void lazyPrintGroupInfo() { if( !currentGroupInfo->name.empty() && currentGroupInfo->groupsCounts > 1 ) { printClosedHeader( "Group: " + currentGroupInfo->name ); currentGroupInfo.used = true; } } void printTestCaseAndSectionHeader() { assert( !m_sectionStack.empty() ); printOpenHeader( currentTestCaseInfo->name ); if( m_sectionStack.size() > 1 ) { Colour colourGuard( Colour::Headers ); std::vector::const_iterator it = m_sectionStack.begin()+1, // Skip first section (test case) itEnd = m_sectionStack.end(); for( ; it != itEnd; ++it ) printHeaderString( it->name, 2 ); } SourceLineInfo lineInfo = m_sectionStack.back().lineInfo; if( !lineInfo.empty() ){ stream << getLineOfChars<'-'>() << '\n'; Colour colourGuard( Colour::FileName ); stream << lineInfo << '\n'; } stream << getLineOfChars<'.'>() << '\n' << std::endl; } void printClosedHeader( std::string const& _name ) { printOpenHeader( _name ); stream << getLineOfChars<'.'>() << '\n'; } void printOpenHeader( std::string const& _name ) { stream << getLineOfChars<'-'>() << '\n'; { Colour colourGuard( Colour::Headers ); printHeaderString( _name ); } } // if string has a : in first line will set indent to follow it on // subsequent lines void printHeaderString( std::string const& _string, std::size_t indent = 0 ) { std::size_t i = _string.find( ": " ); if( i != std::string::npos ) i+=2; else i = 0; stream << Text( _string, TextAttributes() .setIndent( indent+i) .setInitialIndent( indent ) ) << '\n'; } struct SummaryColumn { SummaryColumn( std::string const& _label, Colour::Code _colour ) : label( _label ), colour( _colour ) {} SummaryColumn addRow( std::size_t count ) { std::ostringstream oss; oss << count; std::string row = oss.str(); for( std::vector::iterator it = rows.begin(); it != rows.end(); ++it ) { while( it->size() < row.size() ) *it = ' ' + *it; while( it->size() > row.size() ) row = ' ' + row; } rows.push_back( row ); return *this; } std::string label; Colour::Code colour; std::vector rows; }; void printTotals( Totals const& totals ) { if( totals.testCases.total() == 0 ) { stream << Colour( Colour::Warning ) << "No tests ran\n"; } else if( totals.assertions.total() > 0 && totals.testCases.allPassed() ) { stream << Colour( Colour::ResultSuccess ) << "All tests passed"; stream << " (" << pluralise( totals.assertions.passed, "assertion" ) << " in " << pluralise( totals.testCases.passed, "test case" ) << ')' << '\n'; } else { std::vector columns; columns.push_back( SummaryColumn( "", Colour::None ) .addRow( totals.testCases.total() ) .addRow( totals.assertions.total() ) ); columns.push_back( SummaryColumn( "passed", Colour::Success ) .addRow( totals.testCases.passed ) .addRow( totals.assertions.passed ) ); columns.push_back( SummaryColumn( "failed", Colour::ResultError ) .addRow( totals.testCases.failed ) .addRow( totals.assertions.failed ) ); columns.push_back( SummaryColumn( "failed as expected", Colour::ResultExpectedFailure ) .addRow( totals.testCases.failedButOk ) .addRow( totals.assertions.failedButOk ) ); printSummaryRow( "test cases", columns, 0 ); printSummaryRow( "assertions", columns, 1 ); } } void printSummaryRow( std::string const& label, std::vector const& cols, std::size_t row ) { for( std::vector::const_iterator it = cols.begin(); it != cols.end(); ++it ) { std::string value = it->rows[row]; if( it->label.empty() ) { stream << label << ": "; if( value != "0" ) stream << value; else stream << Colour( Colour::Warning ) << "- none -"; } else if( value != "0" ) { stream << Colour( Colour::LightGrey ) << " | "; stream << Colour( it->colour ) << value << ' ' << it->label; } } stream << '\n'; } static std::size_t makeRatio( std::size_t number, std::size_t total ) { std::size_t ratio = total > 0 ? CATCH_CONFIG_CONSOLE_WIDTH * number/ total : 0; return ( ratio == 0 && number > 0 ) ? 1 : ratio; } static std::size_t& findMax( std::size_t& i, std::size_t& j, std::size_t& k ) { if( i > j && i > k ) return i; else if( j > k ) return j; else return k; } void printTotalsDivider( Totals const& totals ) { if( totals.testCases.total() > 0 ) { std::size_t failedRatio = makeRatio( totals.testCases.failed, totals.testCases.total() ); std::size_t failedButOkRatio = makeRatio( totals.testCases.failedButOk, totals.testCases.total() ); std::size_t passedRatio = makeRatio( totals.testCases.passed, totals.testCases.total() ); while( failedRatio + failedButOkRatio + passedRatio < CATCH_CONFIG_CONSOLE_WIDTH-1 ) findMax( failedRatio, failedButOkRatio, passedRatio )++; while( failedRatio + failedButOkRatio + passedRatio > CATCH_CONFIG_CONSOLE_WIDTH-1 ) findMax( failedRatio, failedButOkRatio, passedRatio )--; stream << Colour( Colour::Error ) << std::string( failedRatio, '=' ); stream << Colour( Colour::ResultExpectedFailure ) << std::string( failedButOkRatio, '=' ); if( totals.testCases.allPassed() ) stream << Colour( Colour::ResultSuccess ) << std::string( passedRatio, '=' ); else stream << Colour( Colour::Success ) << std::string( passedRatio, '=' ); } else { stream << Colour( Colour::Warning ) << std::string( CATCH_CONFIG_CONSOLE_WIDTH-1, '=' ); } stream << '\n'; } void printSummaryDivider() { stream << getLineOfChars<'-'>() << '\n'; } private: bool m_headerPrinted; }; INTERNAL_CATCH_REGISTER_REPORTER( "console", ConsoleReporter ) } // end namespace Catch #endif // TWOBLUECUBES_CATCH_REPORTER_CONSOLE_HPP_INCLUDED catch-1.12.1/include/reporters/catch_reporter_junit.hpp000066400000000000000000000243021325474075300232670ustar00rootroot00000000000000/* * Created by Phil on 26/11/2010. * Copyright 2010 Two Blue Cubes Ltd. All rights reserved. * * Distributed under the Boost Software License, Version 1.0. (See accompanying * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) */ #ifndef TWOBLUECUBES_CATCH_REPORTER_JUNIT_HPP_INCLUDED #define TWOBLUECUBES_CATCH_REPORTER_JUNIT_HPP_INCLUDED #include "catch_reporter_bases.hpp" #include "../internal/catch_tostring.h" #include "../internal/catch_reporter_registrars.hpp" #include "../internal/catch_xmlwriter.hpp" #include namespace Catch { namespace { std::string getCurrentTimestamp() { // Beware, this is not reentrant because of backward compatibility issues // Also, UTC only, again because of backward compatibility (%z is C++11) time_t rawtime; std::time(&rawtime); const size_t timeStampSize = sizeof("2017-01-16T17:06:45Z"); #ifdef _MSC_VER std::tm timeInfo = {}; gmtime_s(&timeInfo, &rawtime); #else std::tm* timeInfo; timeInfo = std::gmtime(&rawtime); #endif char timeStamp[timeStampSize]; const char * const fmt = "%Y-%m-%dT%H:%M:%SZ"; #ifdef _MSC_VER std::strftime(timeStamp, timeStampSize, fmt, &timeInfo); #else std::strftime(timeStamp, timeStampSize, fmt, timeInfo); #endif return std::string(timeStamp); } } class JunitReporter : public CumulativeReporterBase { public: JunitReporter( ReporterConfig const& _config ) : CumulativeReporterBase( _config ), xml( _config.stream() ), unexpectedExceptions( 0 ), m_okToFail( false ) { m_reporterPrefs.shouldRedirectStdOut = true; } virtual ~JunitReporter() CATCH_OVERRIDE; static std::string getDescription() { return "Reports test results in an XML format that looks like Ant's junitreport target"; } virtual void noMatchingTestCases( std::string const& /*spec*/ ) CATCH_OVERRIDE {} virtual void testRunStarting( TestRunInfo const& runInfo ) CATCH_OVERRIDE { CumulativeReporterBase::testRunStarting( runInfo ); xml.startElement( "testsuites" ); } virtual void testGroupStarting( GroupInfo const& groupInfo ) CATCH_OVERRIDE { suiteTimer.start(); stdOutForSuite.str(""); stdErrForSuite.str(""); unexpectedExceptions = 0; CumulativeReporterBase::testGroupStarting( groupInfo ); } virtual void testCaseStarting( TestCaseInfo const& testCaseInfo ) CATCH_OVERRIDE { m_okToFail = testCaseInfo.okToFail(); } virtual bool assertionEnded( AssertionStats const& assertionStats ) CATCH_OVERRIDE { if( assertionStats.assertionResult.getResultType() == ResultWas::ThrewException && !m_okToFail ) unexpectedExceptions++; return CumulativeReporterBase::assertionEnded( assertionStats ); } virtual void testCaseEnded( TestCaseStats const& testCaseStats ) CATCH_OVERRIDE { stdOutForSuite << testCaseStats.stdOut; stdErrForSuite << testCaseStats.stdErr; CumulativeReporterBase::testCaseEnded( testCaseStats ); } virtual void testGroupEnded( TestGroupStats const& testGroupStats ) CATCH_OVERRIDE { double suiteTime = suiteTimer.getElapsedSeconds(); CumulativeReporterBase::testGroupEnded( testGroupStats ); writeGroup( *m_testGroups.back(), suiteTime ); } virtual void testRunEndedCumulative() CATCH_OVERRIDE { xml.endElement(); } void writeGroup( TestGroupNode const& groupNode, double suiteTime ) { XmlWriter::ScopedElement e = xml.scopedElement( "testsuite" ); TestGroupStats const& stats = groupNode.value; xml.writeAttribute( "name", stats.groupInfo.name ); xml.writeAttribute( "errors", unexpectedExceptions ); xml.writeAttribute( "failures", stats.totals.assertions.failed-unexpectedExceptions ); xml.writeAttribute( "tests", stats.totals.assertions.total() ); xml.writeAttribute( "hostname", "tbd" ); // !TBD if( m_config->showDurations() == ShowDurations::Never ) xml.writeAttribute( "time", "" ); else xml.writeAttribute( "time", suiteTime ); xml.writeAttribute( "timestamp", getCurrentTimestamp() ); // Write test cases for( TestGroupNode::ChildNodes::const_iterator it = groupNode.children.begin(), itEnd = groupNode.children.end(); it != itEnd; ++it ) writeTestCase( **it ); xml.scopedElement( "system-out" ).writeText( trim( stdOutForSuite.str() ), false ); xml.scopedElement( "system-err" ).writeText( trim( stdErrForSuite.str() ), false ); } void writeTestCase( TestCaseNode const& testCaseNode ) { TestCaseStats const& stats = testCaseNode.value; // All test cases have exactly one section - which represents the // test case itself. That section may have 0-n nested sections assert( testCaseNode.children.size() == 1 ); SectionNode const& rootSection = *testCaseNode.children.front(); std::string className = stats.testInfo.className; if( className.empty() ) { if( rootSection.childSections.empty() ) className = "global"; } writeSection( className, "", rootSection ); } void writeSection( std::string const& className, std::string const& rootName, SectionNode const& sectionNode ) { std::string name = trim( sectionNode.stats.sectionInfo.name ); if( !rootName.empty() ) name = rootName + '/' + name; if( !sectionNode.assertions.empty() || !sectionNode.stdOut.empty() || !sectionNode.stdErr.empty() ) { XmlWriter::ScopedElement e = xml.scopedElement( "testcase" ); if( className.empty() ) { xml.writeAttribute( "classname", name ); xml.writeAttribute( "name", "root" ); } else { xml.writeAttribute( "classname", className ); xml.writeAttribute( "name", name ); } xml.writeAttribute( "time", Catch::toString( sectionNode.stats.durationInSeconds ) ); writeAssertions( sectionNode ); if( !sectionNode.stdOut.empty() ) xml.scopedElement( "system-out" ).writeText( trim( sectionNode.stdOut ), false ); if( !sectionNode.stdErr.empty() ) xml.scopedElement( "system-err" ).writeText( trim( sectionNode.stdErr ), false ); } for( SectionNode::ChildSections::const_iterator it = sectionNode.childSections.begin(), itEnd = sectionNode.childSections.end(); it != itEnd; ++it ) if( className.empty() ) writeSection( name, "", **it ); else writeSection( className, name, **it ); } void writeAssertions( SectionNode const& sectionNode ) { for( SectionNode::Assertions::const_iterator it = sectionNode.assertions.begin(), itEnd = sectionNode.assertions.end(); it != itEnd; ++it ) writeAssertion( *it ); } void writeAssertion( AssertionStats const& stats ) { AssertionResult const& result = stats.assertionResult; if( !result.isOk() ) { std::string elementName; switch( result.getResultType() ) { case ResultWas::ThrewException: case ResultWas::FatalErrorCondition: elementName = "error"; break; case ResultWas::ExplicitFailure: elementName = "failure"; break; case ResultWas::ExpressionFailed: elementName = "failure"; break; case ResultWas::DidntThrowException: elementName = "failure"; break; // We should never see these here: case ResultWas::Info: case ResultWas::Warning: case ResultWas::Ok: case ResultWas::Unknown: case ResultWas::FailureBit: case ResultWas::Exception: elementName = "internalError"; break; } XmlWriter::ScopedElement e = xml.scopedElement( elementName ); xml.writeAttribute( "message", result.getExpandedExpression() ); xml.writeAttribute( "type", result.getTestMacroName() ); std::ostringstream oss; if( !result.getMessage().empty() ) oss << result.getMessage() << '\n'; for( std::vector::const_iterator it = stats.infoMessages.begin(), itEnd = stats.infoMessages.end(); it != itEnd; ++it ) if( it->type == ResultWas::Info ) oss << it->message << '\n'; oss << "at " << result.getSourceInfo(); xml.writeText( oss.str(), false ); } } XmlWriter xml; Timer suiteTimer; std::ostringstream stdOutForSuite; std::ostringstream stdErrForSuite; unsigned int unexpectedExceptions; bool m_okToFail; }; INTERNAL_CATCH_REGISTER_REPORTER( "junit", JunitReporter ) } // end namespace Catch #endif // TWOBLUECUBES_CATCH_REPORTER_JUNIT_HPP_INCLUDED catch-1.12.1/include/reporters/catch_reporter_multi.hpp000066400000000000000000000123331325474075300232710ustar00rootroot00000000000000/* * Created by Phil on 5/08/2015. * Copyright 2015 Two Blue Cubes Ltd. All rights reserved. * * Distributed under the Boost Software License, Version 1.0. (See accompanying * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) */ #ifndef TWOBLUECUBES_CATCH_REPORTER_MULTI_HPP_INCLUDED #define TWOBLUECUBES_CATCH_REPORTER_MULTI_HPP_INCLUDED #include "../internal/catch_interfaces_reporter.h" namespace Catch { class MultipleReporters : public SharedImpl { typedef std::vector > Reporters; Reporters m_reporters; public: void add( Ptr const& reporter ) { m_reporters.push_back( reporter ); } public: // IStreamingReporter virtual ReporterPreferences getPreferences() const CATCH_OVERRIDE { return m_reporters[0]->getPreferences(); } virtual void noMatchingTestCases( std::string const& spec ) CATCH_OVERRIDE { for( Reporters::const_iterator it = m_reporters.begin(), itEnd = m_reporters.end(); it != itEnd; ++it ) (*it)->noMatchingTestCases( spec ); } virtual void testRunStarting( TestRunInfo const& testRunInfo ) CATCH_OVERRIDE { for( Reporters::const_iterator it = m_reporters.begin(), itEnd = m_reporters.end(); it != itEnd; ++it ) (*it)->testRunStarting( testRunInfo ); } virtual void testGroupStarting( GroupInfo const& groupInfo ) CATCH_OVERRIDE { for( Reporters::const_iterator it = m_reporters.begin(), itEnd = m_reporters.end(); it != itEnd; ++it ) (*it)->testGroupStarting( groupInfo ); } virtual void testCaseStarting( TestCaseInfo const& testInfo ) CATCH_OVERRIDE { for( Reporters::const_iterator it = m_reporters.begin(), itEnd = m_reporters.end(); it != itEnd; ++it ) (*it)->testCaseStarting( testInfo ); } virtual void sectionStarting( SectionInfo const& sectionInfo ) CATCH_OVERRIDE { for( Reporters::const_iterator it = m_reporters.begin(), itEnd = m_reporters.end(); it != itEnd; ++it ) (*it)->sectionStarting( sectionInfo ); } virtual void assertionStarting( AssertionInfo const& assertionInfo ) CATCH_OVERRIDE { for( Reporters::const_iterator it = m_reporters.begin(), itEnd = m_reporters.end(); it != itEnd; ++it ) (*it)->assertionStarting( assertionInfo ); } // The return value indicates if the messages buffer should be cleared: virtual bool assertionEnded( AssertionStats const& assertionStats ) CATCH_OVERRIDE { bool clearBuffer = false; for( Reporters::const_iterator it = m_reporters.begin(), itEnd = m_reporters.end(); it != itEnd; ++it ) clearBuffer |= (*it)->assertionEnded( assertionStats ); return clearBuffer; } virtual void sectionEnded( SectionStats const& sectionStats ) CATCH_OVERRIDE { for( Reporters::const_iterator it = m_reporters.begin(), itEnd = m_reporters.end(); it != itEnd; ++it ) (*it)->sectionEnded( sectionStats ); } virtual void testCaseEnded( TestCaseStats const& testCaseStats ) CATCH_OVERRIDE { for( Reporters::const_iterator it = m_reporters.begin(), itEnd = m_reporters.end(); it != itEnd; ++it ) (*it)->testCaseEnded( testCaseStats ); } virtual void testGroupEnded( TestGroupStats const& testGroupStats ) CATCH_OVERRIDE { for( Reporters::const_iterator it = m_reporters.begin(), itEnd = m_reporters.end(); it != itEnd; ++it ) (*it)->testGroupEnded( testGroupStats ); } virtual void testRunEnded( TestRunStats const& testRunStats ) CATCH_OVERRIDE { for( Reporters::const_iterator it = m_reporters.begin(), itEnd = m_reporters.end(); it != itEnd; ++it ) (*it)->testRunEnded( testRunStats ); } virtual void skipTest( TestCaseInfo const& testInfo ) CATCH_OVERRIDE { for( Reporters::const_iterator it = m_reporters.begin(), itEnd = m_reporters.end(); it != itEnd; ++it ) (*it)->skipTest( testInfo ); } virtual MultipleReporters* tryAsMulti() CATCH_OVERRIDE { return this; } }; Ptr addReporter( Ptr const& existingReporter, Ptr const& additionalReporter ) { Ptr resultingReporter; if( existingReporter ) { MultipleReporters* multi = existingReporter->tryAsMulti(); if( !multi ) { multi = new MultipleReporters; resultingReporter = Ptr( multi ); if( existingReporter ) multi->add( existingReporter ); } else resultingReporter = existingReporter; multi->add( additionalReporter ); } else resultingReporter = additionalReporter; return resultingReporter; } } // end namespace Catch #endif // TWOBLUECUBES_CATCH_REPORTER_MULTI_HPP_INCLUDED catch-1.12.1/include/reporters/catch_reporter_tap.hpp000066400000000000000000000226731325474075300227330ustar00rootroot00000000000000/* * Created by Colton Wolkins on 2015-08-15. * Copyright 2015 Martin Moene. All rights reserved. * * Distributed under the Boost Software License, Version 1.0. (See accompanying * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) */ #ifndef TWOBLUECUBES_CATCH_REPORTER_TAP_HPP_INCLUDED #define TWOBLUECUBES_CATCH_REPORTER_TAP_HPP_INCLUDED // Don't #include any Catch headers here - we can assume they are already // included before this header. // This is not good practice in general but is necessary in this case so this // file can be distributed as a single header that works with the main // Catch single header. #include namespace Catch { struct TAPReporter : StreamingReporterBase { TAPReporter( ReporterConfig const& _config ) : StreamingReporterBase( _config ), counter(0) {} virtual ~TAPReporter(); static std::string getDescription() { return "Reports test results in TAP format, suitable for test harneses"; } virtual ReporterPreferences getPreferences() const { ReporterPreferences prefs; prefs.shouldRedirectStdOut = false; return prefs; } virtual void noMatchingTestCases( std::string const& spec ) { stream << "# No test cases matched '" << spec << "'" << std::endl; } virtual void assertionStarting( AssertionInfo const& ) {} virtual bool assertionEnded( AssertionStats const& _assertionStats ) { ++counter; AssertionPrinter printer( stream, _assertionStats, counter ); printer.print(); stream << " # " << currentTestCaseInfo->name ; stream << std::endl; return true; } virtual void testRunEnded( TestRunStats const& _testRunStats ) { printTotals( _testRunStats.totals ); stream << "\n" << std::endl; StreamingReporterBase::testRunEnded( _testRunStats ); } private: size_t counter; class AssertionPrinter { void operator= ( AssertionPrinter const& ); public: AssertionPrinter( std::ostream& _stream, AssertionStats const& _stats, size_t counter ) : stream( _stream ) , stats( _stats ) , result( _stats.assertionResult ) , messages( _stats.infoMessages ) , itMessage( _stats.infoMessages.begin() ) , printInfoMessages( true ) , counter(counter) {} void print() { itMessage = messages.begin(); switch( result.getResultType() ) { case ResultWas::Ok: printResultType( passedString() ); printOriginalExpression(); printReconstructedExpression(); if ( ! result.hasExpression() ) printRemainingMessages( Colour::None ); else printRemainingMessages(); break; case ResultWas::ExpressionFailed: if (result.isOk()) { printResultType(passedString()); } else { printResultType(failedString()); } printOriginalExpression(); printReconstructedExpression(); if (result.isOk()) { printIssue(" # TODO"); } printRemainingMessages(); break; case ResultWas::ThrewException: printResultType( failedString() ); printIssue( "unexpected exception with message:" ); printMessage(); printExpressionWas(); printRemainingMessages(); break; case ResultWas::FatalErrorCondition: printResultType( failedString() ); printIssue( "fatal error condition with message:" ); printMessage(); printExpressionWas(); printRemainingMessages(); break; case ResultWas::DidntThrowException: printResultType( failedString() ); printIssue( "expected exception, got none" ); printExpressionWas(); printRemainingMessages(); break; case ResultWas::Info: printResultType( "info" ); printMessage(); printRemainingMessages(); break; case ResultWas::Warning: printResultType( "warning" ); printMessage(); printRemainingMessages(); break; case ResultWas::ExplicitFailure: printResultType( failedString() ); printIssue( "explicitly" ); printRemainingMessages( Colour::None ); break; // These cases are here to prevent compiler warnings case ResultWas::Unknown: case ResultWas::FailureBit: case ResultWas::Exception: printResultType( "** internal error **" ); break; } } private: static Colour::Code dimColour() { return Colour::FileName; } static const char* failedString() { return "not ok"; } static const char* passedString() { return "ok"; } void printSourceInfo() const { Colour colourGuard( dimColour() ); stream << result.getSourceInfo() << ":"; } void printResultType( std::string const& passOrFail ) const { if( !passOrFail.empty() ) { stream << passOrFail << ' ' << counter << " -"; } } void printIssue( std::string const& issue ) const { stream << " " << issue; } void printExpressionWas() { if( result.hasExpression() ) { stream << ";"; { Colour colour( dimColour() ); stream << " expression was:"; } printOriginalExpression(); } } void printOriginalExpression() const { if( result.hasExpression() ) { stream << " " << result.getExpression(); } } void printReconstructedExpression() const { if( result.hasExpandedExpression() ) { { Colour colour( dimColour() ); stream << " for: "; } std::string expr = result.getExpandedExpression(); std::replace( expr.begin(), expr.end(), '\n', ' '); stream << expr; } } void printMessage() { if ( itMessage != messages.end() ) { stream << " '" << itMessage->message << "'"; ++itMessage; } } void printRemainingMessages( Colour::Code colour = dimColour() ) { if (itMessage == messages.end()) { return; } // using messages.end() directly yields compilation error: std::vector::const_iterator itEnd = messages.end(); const std::size_t N = static_cast( std::distance( itMessage, itEnd ) ); { Colour colourGuard( colour ); stream << " with " << pluralise( N, "message" ) << ":"; } for(; itMessage != itEnd; ) { // If this assertion is a warning ignore any INFO messages if( printInfoMessages || itMessage->type != ResultWas::Info ) { stream << " '" << itMessage->message << "'"; if ( ++itMessage != itEnd ) { Colour colourGuard( dimColour() ); stream << " and"; } } } } private: std::ostream& stream; AssertionStats const& stats; AssertionResult const& result; std::vector messages; std::vector::const_iterator itMessage; bool printInfoMessages; size_t counter; }; void printTotals( const Totals& totals ) const { if( totals.testCases.total() == 0 ) { stream << "1..0 # Skipped: No tests ran."; } else { stream << "1.." << counter; } } }; #ifdef CATCH_IMPL TAPReporter::~TAPReporter() {} #endif INTERNAL_CATCH_REGISTER_REPORTER( "tap", TAPReporter ) } // end namespace Catch #endif // TWOBLUECUBES_CATCH_REPORTER_TAP_HPP_INCLUDED catch-1.12.1/include/reporters/catch_reporter_teamcity.hpp000066400000000000000000000216401325474075300237570ustar00rootroot00000000000000/* * Created by Phil Nash on 19th December 2014 * Copyright 2014 Two Blue Cubes Ltd. All rights reserved. * * Distributed under the Boost Software License, Version 1.0. (See accompanying * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) */ #ifndef TWOBLUECUBES_CATCH_REPORTER_TEAMCITY_HPP_INCLUDED #define TWOBLUECUBES_CATCH_REPORTER_TEAMCITY_HPP_INCLUDED // Don't #include any Catch headers here - we can assume they are already // included before this header. // This is not good practice in general but is necessary in this case so this // file can be distributed as a single header that works with the main // Catch single header. #include #ifdef __clang__ # pragma clang diagnostic push # pragma clang diagnostic ignored "-Wpadded" # pragma clang diagnostic ignored "-Wc++98-compat" # pragma clang diagnostic ignored "-Wc++98-compat-pedantic" #endif namespace Catch { struct TeamCityReporter : StreamingReporterBase { TeamCityReporter( ReporterConfig const& _config ) : StreamingReporterBase( _config ), m_headerPrintedForThisSection( false ) { m_reporterPrefs.shouldRedirectStdOut = true; } static std::string escape( std::string const& str ) { std::string escaped = str; replaceInPlace( escaped, "|", "||" ); replaceInPlace( escaped, "'", "|'" ); replaceInPlace( escaped, "\n", "|n" ); replaceInPlace( escaped, "\r", "|r" ); replaceInPlace( escaped, "[", "|[" ); replaceInPlace( escaped, "]", "|]" ); return escaped; } virtual ~TeamCityReporter() CATCH_OVERRIDE; static std::string getDescription() { return "Reports test results as TeamCity service messages"; } virtual void skipTest( TestCaseInfo const& /* testInfo */ ) CATCH_OVERRIDE { } virtual void noMatchingTestCases( std::string const& /* spec */ ) CATCH_OVERRIDE {} virtual void testGroupStarting( GroupInfo const& groupInfo ) CATCH_OVERRIDE { StreamingReporterBase::testGroupStarting( groupInfo ); stream << "##teamcity[testSuiteStarted name='" << escape( groupInfo.name ) << "']\n"; } virtual void testGroupEnded( TestGroupStats const& testGroupStats ) CATCH_OVERRIDE { StreamingReporterBase::testGroupEnded( testGroupStats ); stream << "##teamcity[testSuiteFinished name='" << escape( testGroupStats.groupInfo.name ) << "']\n"; } virtual void assertionStarting( AssertionInfo const& ) CATCH_OVERRIDE { } virtual bool assertionEnded( AssertionStats const& assertionStats ) CATCH_OVERRIDE { AssertionResult const& result = assertionStats.assertionResult; if( !result.isOk() ) { std::ostringstream msg; if( !m_headerPrintedForThisSection ) printSectionHeader( msg ); m_headerPrintedForThisSection = true; msg << result.getSourceInfo() << "\n"; switch( result.getResultType() ) { case ResultWas::ExpressionFailed: msg << "expression failed"; break; case ResultWas::ThrewException: msg << "unexpected exception"; break; case ResultWas::FatalErrorCondition: msg << "fatal error condition"; break; case ResultWas::DidntThrowException: msg << "no exception was thrown where one was expected"; break; case ResultWas::ExplicitFailure: msg << "explicit failure"; break; // We shouldn't get here because of the isOk() test case ResultWas::Ok: case ResultWas::Info: case ResultWas::Warning: // These cases are here to prevent compiler warnings case ResultWas::Unknown: case ResultWas::FailureBit: case ResultWas::Exception: CATCH_NOT_IMPLEMENTED; } if( assertionStats.infoMessages.size() == 1 ) msg << " with message:"; if( assertionStats.infoMessages.size() > 1 ) msg << " with messages:"; for( std::vector::const_iterator it = assertionStats.infoMessages.begin(), itEnd = assertionStats.infoMessages.end(); it != itEnd; ++it ) msg << "\n \"" << it->message << "\""; if( result.hasExpression() ) { msg << "\n " << result.getExpressionInMacro() << "\n" "with expansion:\n" << " " << result.getExpandedExpression() << "\n"; } if( currentTestCaseInfo->okToFail() ) { msg << "- failure ignore as test marked as 'ok to fail'\n"; stream << "##teamcity[testIgnored" << " name='" << escape( currentTestCaseInfo->name )<< "'" << " message='" << escape( msg.str() ) << "'" << "]\n"; } else { stream << "##teamcity[testFailed" << " name='" << escape( currentTestCaseInfo->name )<< "'" << " message='" << escape( msg.str() ) << "'" << "]\n"; } } stream.flush(); return true; } virtual void sectionStarting( SectionInfo const& sectionInfo ) CATCH_OVERRIDE { m_headerPrintedForThisSection = false; StreamingReporterBase::sectionStarting( sectionInfo ); } virtual void testCaseStarting( TestCaseInfo const& testInfo ) CATCH_OVERRIDE { m_testTimer.start(); StreamingReporterBase::testCaseStarting( testInfo ); stream << "##teamcity[testStarted name='" << escape( testInfo.name ) << "']\n"; stream.flush(); } virtual void testCaseEnded( TestCaseStats const& testCaseStats ) CATCH_OVERRIDE { StreamingReporterBase::testCaseEnded( testCaseStats ); if( !testCaseStats.stdOut.empty() ) stream << "##teamcity[testStdOut name='" << escape( testCaseStats.testInfo.name ) << "' out='" << escape( testCaseStats.stdOut ) << "']\n"; if( !testCaseStats.stdErr.empty() ) stream << "##teamcity[testStdErr name='" << escape( testCaseStats.testInfo.name ) << "' out='" << escape( testCaseStats.stdErr ) << "']\n"; stream << "##teamcity[testFinished name='" << escape( testCaseStats.testInfo.name ) << "' duration='" << m_testTimer.getElapsedMilliseconds() << "']\n"; stream.flush(); } private: void printSectionHeader( std::ostream& os ) { assert( !m_sectionStack.empty() ); if( m_sectionStack.size() > 1 ) { os << getLineOfChars<'-'>() << "\n"; std::vector::const_iterator it = m_sectionStack.begin()+1, // Skip first section (test case) itEnd = m_sectionStack.end(); for( ; it != itEnd; ++it ) printHeaderString( os, it->name ); os << getLineOfChars<'-'>() << "\n"; } SourceLineInfo lineInfo = m_sectionStack.front().lineInfo; if( !lineInfo.empty() ) os << lineInfo << "\n"; os << getLineOfChars<'.'>() << "\n\n"; } // if string has a : in first line will set indent to follow it on // subsequent lines void printHeaderString( std::ostream& os, std::string const& _string, std::size_t indent = 0 ) { std::size_t i = _string.find( ": " ); if( i != std::string::npos ) i+=2; else i = 0; os << Text( _string, TextAttributes() .setIndent( indent+i) .setInitialIndent( indent ) ) << "\n"; } private: bool m_headerPrintedForThisSection; Timer m_testTimer; }; #ifdef CATCH_IMPL TeamCityReporter::~TeamCityReporter() {} #endif INTERNAL_CATCH_REGISTER_REPORTER( "teamcity", TeamCityReporter ) } // end namespace Catch #ifdef __clang__ # pragma clang diagnostic pop #endif #endif // TWOBLUECUBES_CATCH_REPORTER_TEAMCITY_HPP_INCLUDED catch-1.12.1/include/reporters/catch_reporter_xml.hpp000066400000000000000000000231161325474075300227400ustar00rootroot00000000000000/* * Created by Phil on 28/10/2010. * Copyright 2010 Two Blue Cubes Ltd. All rights reserved. * * Distributed under the Boost Software License, Version 1.0. (See accompanying * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) */ #ifndef TWOBLUECUBES_CATCH_REPORTER_XML_HPP_INCLUDED #define TWOBLUECUBES_CATCH_REPORTER_XML_HPP_INCLUDED #include "catch_reporter_bases.hpp" #include "../internal/catch_capture.hpp" #include "../internal/catch_reporter_registrars.hpp" #include "../internal/catch_xmlwriter.hpp" #include "../internal/catch_timer.h" namespace Catch { class XmlReporter : public StreamingReporterBase { public: XmlReporter( ReporterConfig const& _config ) : StreamingReporterBase( _config ), m_xml(_config.stream()), m_sectionDepth( 0 ) { m_reporterPrefs.shouldRedirectStdOut = true; } virtual ~XmlReporter() CATCH_OVERRIDE; static std::string getDescription() { return "Reports test results as an XML document"; } virtual std::string getStylesheetRef() const { return std::string(); } void writeSourceInfo( SourceLineInfo const& sourceInfo ) { m_xml .writeAttribute( "filename", sourceInfo.file ) .writeAttribute( "line", sourceInfo.line ); } public: // StreamingReporterBase virtual void noMatchingTestCases( std::string const& s ) CATCH_OVERRIDE { StreamingReporterBase::noMatchingTestCases( s ); } virtual void testRunStarting( TestRunInfo const& testInfo ) CATCH_OVERRIDE { StreamingReporterBase::testRunStarting( testInfo ); std::string stylesheetRef = getStylesheetRef(); if( !stylesheetRef.empty() ) m_xml.writeStylesheetRef( stylesheetRef ); m_xml.startElement( "Catch" ); if( !m_config->name().empty() ) m_xml.writeAttribute( "name", m_config->name() ); } virtual void testGroupStarting( GroupInfo const& groupInfo ) CATCH_OVERRIDE { StreamingReporterBase::testGroupStarting( groupInfo ); m_xml.startElement( "Group" ) .writeAttribute( "name", groupInfo.name ); } virtual void testCaseStarting( TestCaseInfo const& testInfo ) CATCH_OVERRIDE { StreamingReporterBase::testCaseStarting(testInfo); m_xml.startElement( "TestCase" ) .writeAttribute( "name", trim( testInfo.name ) ) .writeAttribute( "description", testInfo.description ) .writeAttribute( "tags", testInfo.tagsAsString ); writeSourceInfo( testInfo.lineInfo ); if ( m_config->showDurations() == ShowDurations::Always ) m_testCaseTimer.start(); m_xml.ensureTagClosed(); } virtual void sectionStarting( SectionInfo const& sectionInfo ) CATCH_OVERRIDE { StreamingReporterBase::sectionStarting( sectionInfo ); if( m_sectionDepth++ > 0 ) { m_xml.startElement( "Section" ) .writeAttribute( "name", trim( sectionInfo.name ) ) .writeAttribute( "description", sectionInfo.description ); writeSourceInfo( sectionInfo.lineInfo ); m_xml.ensureTagClosed(); } } virtual void assertionStarting( AssertionInfo const& ) CATCH_OVERRIDE { } virtual bool assertionEnded( AssertionStats const& assertionStats ) CATCH_OVERRIDE { AssertionResult const& result = assertionStats.assertionResult; bool includeResults = m_config->includeSuccessfulResults() || !result.isOk(); if( includeResults || result.getResultType() == ResultWas::Warning ) { // Print any info messages in tags. for( std::vector::const_iterator it = assertionStats.infoMessages.begin(), itEnd = assertionStats.infoMessages.end(); it != itEnd; ++it ) { if( it->type == ResultWas::Info && includeResults ) { m_xml.scopedElement( "Info" ) .writeText( it->message ); } else if ( it->type == ResultWas::Warning ) { m_xml.scopedElement( "Warning" ) .writeText( it->message ); } } } // Drop out if result was successful but we're not printing them. if( !includeResults && result.getResultType() != ResultWas::Warning ) return true; // Print the expression if there is one. if( result.hasExpression() ) { m_xml.startElement( "Expression" ) .writeAttribute( "success", result.succeeded() ) .writeAttribute( "type", result.getTestMacroName() ); writeSourceInfo( result.getSourceInfo() ); m_xml.scopedElement( "Original" ) .writeText( result.getExpression() ); m_xml.scopedElement( "Expanded" ) .writeText( result.getExpandedExpression() ); } // And... Print a result applicable to each result type. switch( result.getResultType() ) { case ResultWas::ThrewException: m_xml.startElement( "Exception" ); writeSourceInfo( result.getSourceInfo() ); m_xml.writeText( result.getMessage() ); m_xml.endElement(); break; case ResultWas::FatalErrorCondition: m_xml.startElement( "FatalErrorCondition" ); writeSourceInfo( result.getSourceInfo() ); m_xml.writeText( result.getMessage() ); m_xml.endElement(); break; case ResultWas::Info: m_xml.scopedElement( "Info" ) .writeText( result.getMessage() ); break; case ResultWas::Warning: // Warning will already have been written break; case ResultWas::ExplicitFailure: m_xml.startElement( "Failure" ); writeSourceInfo( result.getSourceInfo() ); m_xml.writeText( result.getMessage() ); m_xml.endElement(); break; default: break; } if( result.hasExpression() ) m_xml.endElement(); return true; } virtual void sectionEnded( SectionStats const& sectionStats ) CATCH_OVERRIDE { StreamingReporterBase::sectionEnded( sectionStats ); if( --m_sectionDepth > 0 ) { XmlWriter::ScopedElement e = m_xml.scopedElement( "OverallResults" ); e.writeAttribute( "successes", sectionStats.assertions.passed ); e.writeAttribute( "failures", sectionStats.assertions.failed ); e.writeAttribute( "expectedFailures", sectionStats.assertions.failedButOk ); if ( m_config->showDurations() == ShowDurations::Always ) e.writeAttribute( "durationInSeconds", sectionStats.durationInSeconds ); m_xml.endElement(); } } virtual void testCaseEnded( TestCaseStats const& testCaseStats ) CATCH_OVERRIDE { StreamingReporterBase::testCaseEnded( testCaseStats ); XmlWriter::ScopedElement e = m_xml.scopedElement( "OverallResult" ); e.writeAttribute( "success", testCaseStats.totals.assertions.allOk() ); if ( m_config->showDurations() == ShowDurations::Always ) e.writeAttribute( "durationInSeconds", m_testCaseTimer.getElapsedSeconds() ); if( !testCaseStats.stdOut.empty() ) m_xml.scopedElement( "StdOut" ).writeText( trim( testCaseStats.stdOut ), false ); if( !testCaseStats.stdErr.empty() ) m_xml.scopedElement( "StdErr" ).writeText( trim( testCaseStats.stdErr ), false ); m_xml.endElement(); } virtual void testGroupEnded( TestGroupStats const& testGroupStats ) CATCH_OVERRIDE { StreamingReporterBase::testGroupEnded( testGroupStats ); // TODO: Check testGroupStats.aborting and act accordingly. m_xml.scopedElement( "OverallResults" ) .writeAttribute( "successes", testGroupStats.totals.assertions.passed ) .writeAttribute( "failures", testGroupStats.totals.assertions.failed ) .writeAttribute( "expectedFailures", testGroupStats.totals.assertions.failedButOk ); m_xml.endElement(); } virtual void testRunEnded( TestRunStats const& testRunStats ) CATCH_OVERRIDE { StreamingReporterBase::testRunEnded( testRunStats ); m_xml.scopedElement( "OverallResults" ) .writeAttribute( "successes", testRunStats.totals.assertions.passed ) .writeAttribute( "failures", testRunStats.totals.assertions.failed ) .writeAttribute( "expectedFailures", testRunStats.totals.assertions.failedButOk ); m_xml.endElement(); } private: Timer m_testCaseTimer; XmlWriter m_xml; int m_sectionDepth; }; INTERNAL_CATCH_REGISTER_REPORTER( "xml", XmlReporter ) } // end namespace Catch #endif // TWOBLUECUBES_CATCH_REPORTER_XML_HPP_INCLUDED catch-1.12.1/projects/000077500000000000000000000000001325474075300145215ustar00rootroot00000000000000catch-1.12.1/projects/Benchmark/000077500000000000000000000000001325474075300164135ustar00rootroot00000000000000catch-1.12.1/projects/Benchmark/BenchMain.cpp000066400000000000000000000003721325474075300207450ustar00rootroot00000000000000/* * Created by Martin on 16/01/2017. * * Distributed under the Boost Software License, Version 1.0. (See accompanying * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) */ #define CATCH_CONFIG_MAIN #include "catch.hpp" catch-1.12.1/projects/Benchmark/StringificationBench.cpp000066400000000000000000000023041325474075300232120ustar00rootroot00000000000000/* * Created by Martin on 16/01/2017. * * Distributed under the Boost Software License, Version 1.0. (See accompanying * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) */ #include "catch.hpp" #include /////////////////////////////////////////////////////////////////////////////// TEST_CASE("Successful tests -- REQUIRE", "[Success]") { const size_t sz = 1 * 1024 * 1024; std::vector vec; vec.reserve(sz); for (size_t i = 0; i < sz; ++i){ vec.push_back(i); REQUIRE(vec.back() == i); } } /////////////////////////////////////////////////////////////////////////////// TEST_CASE("Successful tests -- CHECK", "[Success]") { const size_t sz = 1 * 1024 * 1024; std::vector vec; vec.reserve(sz); for (size_t i = 0; i < sz; ++i){ vec.push_back(i); CHECK(vec.back() == i); } } /////////////////////////////////////////////////////////////////////////////// TEST_CASE("Unsuccessful tests -- CHECK", "[Failure]") { const size_t sz = 1024 * 1024; std::vector vec; vec.reserve(sz); for (size_t i = 0; i < sz; ++i){ vec.push_back(i); CHECK(vec.size() == i); } } catch-1.12.1/projects/Benchmark/readme.txt000066400000000000000000000003671325474075300204170ustar00rootroot00000000000000This is very much a work in progress. The past results are standardized to a developer's machine, the benchmarking script is basic and there are only 3 benchmarks, but this should get better in time. For now, at least there is something to go by. catch-1.12.1/projects/Benchmark/results/000077500000000000000000000000001325474075300201145ustar00rootroot000000000000002017-01-14T21-53-49-e3659cdddd43ba4df9e4846630be6a6a7bd85a07.result000066400000000000000000000003661325474075300311710ustar00rootroot00000000000000catch-1.12.1/projects/Benchmark/resultsSuccessful tests -- CHECK: median: 3.38116 (s), stddev: 0.11567366292001534 (s) Successful tests -- REQUIRE: median: 3.479955 (s), stddev: 0.16295972890734556 (s) Unsuccessful tests -- CHECK: median: 1.966895 (s), stddev: 0.06323488524716572 (s) 2017-01-14T21-59-08-a1e9b841ff500b2f39ccfd4193ae450cb653da05.result000066400000000000000000000003651325474075300310610ustar00rootroot00000000000000catch-1.12.1/projects/Benchmark/resultsSuccessful tests -- CHECK: median: 1.30312 (s), stddev: 0.08759818557862176 (s) Successful tests -- REQUIRE: median: 1.341535 (s), stddev: 0.1479193390143576 (s) Unsuccessful tests -- CHECK: median: 1.967755 (s), stddev: 0.07921104121269959 (s) 2017-01-15T09-35-14-3b98a0166f7b7196eba2ad518174d1a77165166d.result000066400000000000000000000004001325474075300305060ustar00rootroot00000000000000catch-1.12.1/projects/Benchmark/resultsSuccessful tests -- CHECK: median: 1.2982 (s), stddev: 0.019540648829214084 (s) Successful tests -- REQUIRE: median: 1.30102 (s), stddev: 0.014758430547392974 (s) Unsuccessful tests -- CHECK: median: 15.520199999999999 (s), stddev: 0.09536359426485094 (s) 2017-01-29T22-08-36-60f8ebec49c5bc58d3604bf1a72cd3f7d129bf2e.result000066400000000000000000000003741325474075300312440ustar00rootroot00000000000000catch-1.12.1/projects/Benchmark/resultsSuccessful tests -- CHECK: median: 0.7689014999999999 (s), stddev: 0.02127512078801068 (s) Successful tests -- REQUIRE: median: 0.772845 (s), stddev: 0.03011638381365052 (s) Unsuccessful tests -- CHECK: median: 15.49 (s), stddev: 0.536088571143903 (s) 2017-01-29T23-13-35-bcaa2f9646c5ce50758f8582307c99501a932e1a.result000066400000000000000000000004011325474075300305740ustar00rootroot00000000000000catch-1.12.1/projects/Benchmark/resultsSuccessful tests -- CHECK: median: 0.775769 (s), stddev: 0.014802129132136525 (s) Successful tests -- REQUIRE: median: 0.785235 (s), stddev: 0.03532672836834896 (s) Unsuccessful tests -- CHECK: median: 15.156600000000001 (s), stddev: 0.2832375673450742 (s) catch-1.12.1/projects/SelfTest/000077500000000000000000000000001325474075300162525ustar00rootroot00000000000000catch-1.12.1/projects/SelfTest/ApproxTests.cpp000066400000000000000000000120361325474075300212540ustar00rootroot00000000000000/* * Created by Phil on 28/04/2011. * Copyright 2011 Two Blue Cubes Ltd. All rights reserved. * * Distributed under the Boost Software License, Version 1.0. (See accompanying * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) */ #include "catch.hpp" /////////////////////////////////////////////////////////////////////////////// TEST_CASE ( "Some simple comparisons between doubles", "[Approx]" ) { double d = 1.23; REQUIRE( d == Approx( 1.23 ) ); REQUIRE( d != Approx( 1.22 ) ); REQUIRE( d != Approx( 1.24 ) ); REQUIRE( Approx( d ) == 1.23 ); REQUIRE( Approx( d ) != 1.22 ); REQUIRE( Approx( d ) != 1.24 ); REQUIRE( 0 == Approx(0) ); } /////////////////////////////////////////////////////////////////////////////// TEST_CASE ( "Approximate comparisons with different epsilons", "[Approx]" ) { double d = 1.23; REQUIRE( d != Approx( 1.231 ) ); REQUIRE( d == Approx( 1.231 ).epsilon( 0.1 ) ); } /////////////////////////////////////////////////////////////////////////////// TEST_CASE ( "Less-than inequalities with different epsilons", "[Approx]" ) { double d = 1.23; REQUIRE( d <= Approx( 1.24 ) ); REQUIRE( d <= Approx( 1.23 ) ); REQUIRE_FALSE( d <= Approx( 1.22 ) ); REQUIRE( d <= Approx( 1.22 ).epsilon(0.1) ); } /////////////////////////////////////////////////////////////////////////////// TEST_CASE ( "Greater-than inequalities with different epsilons", "[Approx]" ) { double d = 1.23; REQUIRE( d >= Approx( 1.22 ) ); REQUIRE( d >= Approx( 1.23 ) ); REQUIRE_FALSE( d >= Approx( 1.24 ) ); REQUIRE( d >= Approx( 1.24 ).epsilon(0.1) ); } /////////////////////////////////////////////////////////////////////////////// TEST_CASE ( "Approximate comparisons with floats", "[Approx]" ) { REQUIRE( 1.23f == Approx( 1.23f ) ); REQUIRE( 0.0f == Approx( 0.0f ) ); } /////////////////////////////////////////////////////////////////////////////// TEST_CASE ( "Approximate comparisons with ints", "[Approx]" ) { REQUIRE( 1 == Approx( 1 ) ); REQUIRE( 0 == Approx( 0 ) ); } /////////////////////////////////////////////////////////////////////////////// TEST_CASE ( "Approximate comparisons with mixed numeric types", "[Approx]" ) { const double dZero = 0; const double dSmall = 0.00001; const double dMedium = 1.234; REQUIRE( 1.0f == Approx( 1 ) ); REQUIRE( 0 == Approx( dZero) ); REQUIRE( 0 == Approx( dSmall ).epsilon( 0.001 ) ); REQUIRE( 1.234f == Approx( dMedium ) ); REQUIRE( dMedium == Approx( 1.234f ) ); } /////////////////////////////////////////////////////////////////////////////// TEST_CASE ( "Use a custom approx", "[Approx][custom]" ) { double d = 1.23; Approx approx = Approx::custom().epsilon( 0.005 ); REQUIRE( d == approx( 1.23 ) ); REQUIRE( d == approx( 1.22 ) ); REQUIRE( d == approx( 1.24 ) ); REQUIRE( d != approx( 1.25 ) ); REQUIRE( approx( d ) == 1.23 ); REQUIRE( approx( d ) == 1.22 ); REQUIRE( approx( d ) == 1.24 ); REQUIRE( approx( d ) != 1.25 ); } inline double divide( double a, double b ) { return a/b; } TEST_CASE( "Approximate PI", "[Approx][PI]" ) { REQUIRE( divide( 22, 7 ) == Approx( 3.141 ).epsilon( 0.001 ) ); REQUIRE( divide( 22, 7 ) != Approx( 3.141 ).epsilon( 0.0001 ) ); } /////////////////////////////////////////////////////////////////////////////// TEST_CASE( "Absolute margin", "[Approx]" ) { REQUIRE( 104.0 != Approx(100.0) ); REQUIRE( 104.0 == Approx(100.0).margin(5) ); REQUIRE( 104.0 == Approx(100.0).margin(4) ); REQUIRE( 104.0 != Approx(100.0).margin(3) ); REQUIRE( 100.3 != Approx(100.0) ); REQUIRE( 100.3 == Approx(100.0).margin(0.5) ); } TEST_CASE("Approx with exactly-representable margin", "[Approx]") { CHECK( 0.25f == Approx(0.0f).margin(0.25f) ); CHECK( 0.0f == Approx(0.25f).margin(0.25f) ); CHECK( 0.5f == Approx(0.25f).margin(0.25f) ); CHECK( 245.0f == Approx(245.25f).margin(0.25f) ); CHECK( 245.5f == Approx(245.25f).margin(0.25f) ); } //////////////////////////////////////////////////////////////////////////////// #if defined(CATCH_CONFIG_CPP11_TYPE_TRAITS) class StrongDoubleTypedef { double d_ = 0.0; public: explicit StrongDoubleTypedef(double d) : d_(d) {} explicit operator double() const { return d_; } }; inline std::ostream& operator<<( std::ostream& os, StrongDoubleTypedef td ) { return os << "StrongDoubleTypedef(" << static_cast(td) << ")"; } TEST_CASE ( "Comparison with explicitly convertible types", "[Approx][c++11]" ) { StrongDoubleTypedef td(10.0); REQUIRE(td == Approx(10.0)); REQUIRE(Approx(10.0) == td); REQUIRE(td != Approx(11.0)); REQUIRE(Approx(11.0) != td); REQUIRE(td <= Approx(10.0)); REQUIRE(td <= Approx(11.0)); REQUIRE(Approx(10.0) <= td); REQUIRE(Approx(9.0) <= td); REQUIRE(td >= Approx(9.0)); REQUIRE(td >= Approx(10.0)); REQUIRE(Approx(10.0) >= td); REQUIRE(Approx(11.0) >= td); } #endif //////////////////////////////////////////////////////////////////////////////// catch-1.12.1/projects/SelfTest/BDDTests.cpp000066400000000000000000000061341325474075300203760ustar00rootroot00000000000000/* * Created by Phil on 29/11/2010. * Copyright 2010 Two Blue Cubes Ltd. All rights reserved. * * Distributed under the Boost Software License, Version 1.0. (See accompanying * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) */ #include "catch.hpp" inline bool itDoesThis(){ return true; } inline bool itDoesThat(){ return true; } SCENARIO( "Do that thing with the thing", "[Tags]" ) { GIVEN( "This stuff exists" ) { // make stuff exist WHEN( "I do this" ) { // do this THEN( "it should do this") { REQUIRE( itDoesThis() ); AND_THEN( "do that") REQUIRE( itDoesThat() ); } } } } SCENARIO( "Vector resizing affects size and capacity", "[vector][bdd][size][capacity]" ) { GIVEN( "an empty vector" ) { std::vector v; REQUIRE( v.size() == 0 ); WHEN( "it is made larger" ) { v.resize( 10 ); THEN( "the size and capacity go up" ) { REQUIRE( v.size() == 10 ); REQUIRE( v.capacity() >= 10 ); AND_WHEN( "it is made smaller again" ) { v.resize( 5 ); THEN( "the size goes down but the capacity stays the same" ) { REQUIRE( v.size() == 5 ); REQUIRE( v.capacity() >= 10 ); } } } } WHEN( "we reserve more space" ) { v.reserve( 10 ); THEN( "The capacity is increased but the size remains the same" ) { REQUIRE( v.capacity() >= 10 ); REQUIRE( v.size() == 0 ); } } } } SCENARIO( "This is a really long scenario name to see how the list command deals with wrapping", "[very long tags][lots][long][tags][verbose]" "[one very long tag name that should cause line wrapping writing out using the list command]" "[anotherReallyLongTagNameButThisOneHasNoObviousWrapPointsSoShouldSplitWithinAWordUsingADashCharacter]" ) { GIVEN( "A section name that is so long that it cannot fit in a single console width" ) WHEN( "The test headers are printed as part of the normal running of the scenario" ) THEN( "The, deliberately very long and overly verbose (you see what I did there?) section names must wrap, along with an indent" ) SUCCEED("boo!"); } namespace { // a trivial fixture example to support SCENARIO_METHOD tests struct Fixture { Fixture() : d_counter(0) { } int counter() { return d_counter++; } int d_counter; }; } SCENARIO_METHOD(Fixture, "BDD tests requiring Fixtures to provide commonly-accessed data or methods", "[bdd][fixtures]") { const int before(counter()); GIVEN("No operations precede me") { REQUIRE(before == 0); WHEN("We get the count") { const int after(counter()); THEN("Subsequently values are higher") { REQUIRE(after > before); } } } } catch-1.12.1/projects/SelfTest/Baselines/000077500000000000000000000000001325474075300201575ustar00rootroot00000000000000catch-1.12.1/projects/SelfTest/Baselines/automake.std.approved.txt000066400000000000000000000217221325474075300251420ustar00rootroot00000000000000:test-result: PASS # A test name that starts with a # :test-result: PASS #542 :test-result: PASS #809 :test-result: FAIL 'Not' checks that should fail :test-result: PASS 'Not' checks that should succeed :test-result: PASS (unimplemented) static bools can be evaluated :test-result: FAIL A METHOD_AS_TEST_CASE based test run that fails :test-result: PASS A METHOD_AS_TEST_CASE based test run that succeeds :test-result: FAIL A TEST_CASE_METHOD based test run that fails :test-result: PASS A TEST_CASE_METHOD based test run that succeeds :test-result: FAIL A couple of nested sections followed by a failure :test-result: FAIL A failing expression with a non streamable type is still captured :test-result: PASS AllOf matcher :test-result: PASS An empty test with no assertions :test-result: PASS An expression with side-effects should only be evaluated once :test-result: FAIL An unchecked exception reports the line of the last assertion :test-result: PASS Anonymous test case 1 :test-result: PASS AnyOf matcher :test-result: PASS Approximate PI :test-result: PASS Approximate comparisons with different epsilons :test-result: PASS Approximate comparisons with floats :test-result: PASS Approximate comparisons with ints :test-result: PASS Approximate comparisons with mixed numeric types :test-result: PASS Assertions then sections :test-result: PASS Character pretty printing :test-result: PASS Comparing function pointers :test-result: PASS Comparing member function pointers :test-result: PASS Comparisons between ints where one side is computed :test-result: PASS Comparisons between unsigned ints and negative signed ints match c++ standard behaviour :test-result: PASS Comparisons with int literals don't warn when mixing signed/ unsigned :test-result: FAIL Contains string matcher :test-result: FAIL Custom exceptions can be translated when testing for nothrow :test-result: FAIL Custom exceptions can be translated when testing for throwing as something else :test-result: FAIL Custom std-exceptions can be custom translated :test-result: PASS Demonstrate that a non-const == is not used :test-result: FAIL EndsWith string matcher :test-result: XFAIL Equality checks that should fail :test-result: PASS Equality checks that should succeed :test-result: PASS Equals :test-result: FAIL Equals string matcher :test-result: PASS Exception messages can be tested for :test-result: FAIL Expected exceptions that don't throw or unexpected exceptions fail the test :test-result: FAIL FAIL aborts the test :test-result: FAIL FAIL does not require an argument :test-result: PASS Factorials are computed :test-result: PASS Generator over a range of pairs :test-result: PASS Generators over two ranges :test-result: PASS Greater-than inequalities with different epsilons :test-result: PASS INFO and WARN do not abort tests :test-result: FAIL INFO gets logged on failure :test-result: FAIL INFO gets logged on failure, even if captured before successful assertions :test-result: XFAIL Inequality checks that should fail :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 ManuallyRegistered :test-result: PASS Matchers can be (AllOf) composed with the && operator :test-result: PASS Matchers can be (AnyOf) composed with the || operator :test-result: PASS Matchers can be composed with both && and || :test-result: FAIL Matchers can be composed with both && and || - failing :test-result: PASS Matchers can be negated (Not) with the ! operator :test-result: FAIL Matchers can be negated (Not) with the ! operator - failing :test-result: FAIL Mismatching exception messages failing the test :test-result: PASS Nice descriptive name :test-result: FAIL Non-std exceptions can be translated :test-result: PASS NotImplemented exception :test-result: PASS Objects that evaluated in boolean contexts can be checked :test-result: PASS Operators at different namespace levels not hijacked by Koenig lookup :test-result: FAIL Ordering comparison checks that should fail :test-result: PASS Ordering comparison checks that should succeed :test-result: FAIL Output from all sections is reported :test-result: PASS Parse test names and tags :test-result: PASS Parsing a std::pair :test-result: PASS Pointers can be compared to null :test-result: PASS Pointers can be converted to strings :test-result: PASS Process can be configured on command line :test-result: FAIL SCOPED_INFO is reset for each loop :test-result: PASS SUCCEED counts as a test pass :test-result: PASS SUCCESS does not require an argument :test-result: PASS Scenario: BDD tests requiring Fixtures to provide commonly-accessed data or methods :test-result: PASS Scenario: Do that thing with the thing :test-result: PASS Scenario: This is a really long scenario name to see how the list command deals with wrapping :test-result: PASS Scenario: Vector resizing affects size and capacity A string sent directly to stdout A string sent directly to stderr :test-result: PASS Sends stuff to stdout and stderr :test-result: PASS Some simple comparisons between doubles Message from section one Message from section two :test-result: PASS Standard output from all sections is reported :test-result: FAIL StartsWith string matcher :test-result: PASS String matchers hello hello :test-result: PASS Strings can be rendered with colour :test-result: FAIL Tabs and newlines show in output :test-result: PASS Tag alias can be registered against tag patterns :test-result: PASS Test case with one argument :test-result: PASS Test enum bit values :test-result: PASS Text can be formatted using the Text class :test-result: PASS The NO_FAIL macro reports a failure but does not fail the test :test-result: FAIL This test 'should' fail but doesn't :test-result: PASS Tracker :test-result: FAIL Unexpected exceptions can be translated :test-result: PASS Use a custom approx :test-result: PASS Variadic macros :test-result: PASS When checked exceptions are thrown they can be expected or unexpected :test-result: FAIL When unchecked exceptions are thrown directly they are always failures :test-result: FAIL When unchecked exceptions are thrown during a CHECK the test should continue :test-result: FAIL When unchecked exceptions are thrown during a REQUIRE the test should abort fail :test-result: FAIL When unchecked exceptions are thrown from functions they are always failures :test-result: FAIL When unchecked exceptions are thrown from sections they are always failures :test-result: PASS When unchecked exceptions are thrown, but caught, they do not affect the test :test-result: PASS Where the LHS is not a simple value :test-result: PASS Where there is more to the expression after the RHS :test-result: PASS X/level/0/a :test-result: PASS X/level/0/b :test-result: PASS X/level/1/a :test-result: PASS X/level/1/b :test-result: PASS XmlEncode :test-result: PASS atomic if :test-result: PASS boolean member :test-result: PASS checkedElse :test-result: FAIL checkedElse, failing :test-result: PASS checkedIf :test-result: FAIL checkedIf, failing :test-result: PASS comparisons between const int variables :test-result: PASS comparisons between int variables :test-result: PASS even more nested SECTION tests :test-result: PASS first tag spanner:test-result: PASS has printf :test-result: FAIL just failure :test-result: PASS just info :test-result: FAIL looped SECTION tests :test-result: FAIL looped tests :test-result: FAIL more nested SECTION tests :test-result: PASS nested SECTION tests :test-result: PASS non streamable - with conv. op :test-result: PASS not allowed :test-result: PASS null strings :test-result: PASS pair > -> toString :test-result: PASS pointer to class :test-result: PASS random SECTION tests :test-result: PASS replaceInPlace :test-result: PASS second tag :test-result: FAIL send a single char to INFO :test-result: FAIL sends information to INFO :test-result: PASS std::pair -> toString :test-result: PASS std::pair -> toString :test-result: PASS std::vector > -> toString :test-result: FAIL string literals of different sizes can be compared :test-result: PASS toString on const wchar_t const pointer returns the string contents :test-result: PASS toString on const wchar_t pointer returns the string contents :test-result: PASS toString on wchar_t const pointer returns the string contents :test-result: PASS toString on wchar_t returns the string contents :test-result: PASS toString( has_maker ) :test-result: PASS toString( has_maker_and_toString ) :test-result: PASS toString( has_toString ) :test-result: PASS toString( vectors -> toString :test-result: PASS vector -> toString :test-result: PASS vectors can be sized and resized :test-result: PASS xmlentitycheck catch-1.12.1/projects/SelfTest/Baselines/console.std.approved.txt000066400000000000000000000766621325474075300250130ustar00rootroot00000000000000 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ is a host application. Run with -? for options ------------------------------------------------------------------------------- #748 - captures with unexpected exceptions outside assertions ------------------------------------------------------------------------------- ExceptionTests.cpp: ............................................................................... ExceptionTests.cpp:: FAILED: due to unexpected exception with messages: answer := 42 expected exception ------------------------------------------------------------------------------- #748 - captures with unexpected exceptions inside REQUIRE_NOTHROW ------------------------------------------------------------------------------- ExceptionTests.cpp: ............................................................................... ExceptionTests.cpp:: FAILED: REQUIRE_NOTHROW( thisThrows() ) due to unexpected exception with messages: answer := 42 expected exception ------------------------------------------------------------------------------- #835 -- errno should not be touched by Catch ------------------------------------------------------------------------------- MiscTests.cpp: ............................................................................... MiscTests.cpp:: FAILED: CHECK( f() == 0 ) with expansion: 1 == 0 ------------------------------------------------------------------------------- 'Not' checks that should fail ------------------------------------------------------------------------------- ConditionTests.cpp: ............................................................................... ConditionTests.cpp:: FAILED: CHECK( false != false ) ConditionTests.cpp:: FAILED: CHECK( true != true ) ConditionTests.cpp:: FAILED: CHECK( !true ) with expansion: false ConditionTests.cpp:: FAILED: CHECK_FALSE( true ) with expansion: !true ConditionTests.cpp:: FAILED: CHECK( !trueValue ) with expansion: false ConditionTests.cpp:: FAILED: CHECK_FALSE( trueValue ) with expansion: !true ConditionTests.cpp:: FAILED: CHECK( !(1 == 1) ) with expansion: false ConditionTests.cpp:: FAILED: CHECK_FALSE( 1 == 1 ) ------------------------------------------------------------------------------- A METHOD_AS_TEST_CASE based test run that fails ------------------------------------------------------------------------------- ClassTests.cpp: ............................................................................... ClassTests.cpp:: FAILED: REQUIRE( s == "world" ) with expansion: "hello" == "world" ------------------------------------------------------------------------------- A TEST_CASE_METHOD based test run that fails ------------------------------------------------------------------------------- ClassTests.cpp: ............................................................................... ClassTests.cpp:: FAILED: REQUIRE( m_a == 2 ) with expansion: 1 == 2 ------------------------------------------------------------------------------- A couple of nested sections followed by a failure ------------------------------------------------------------------------------- MiscTests.cpp: ............................................................................... MiscTests.cpp:: FAILED: explicitly with message: to infinity and beyond ------------------------------------------------------------------------------- A failing expression with a non streamable type is still captured ------------------------------------------------------------------------------- TrickyTests.cpp: ............................................................................... TrickyTests.cpp:: FAILED: CHECK( &o1 == &o2 ) with expansion: 0x == 0x TrickyTests.cpp:: FAILED: CHECK( o1 == o2 ) with expansion: {?} == {?} ------------------------------------------------------------------------------- An unchecked exception reports the line of the last assertion ------------------------------------------------------------------------------- ExceptionTests.cpp: ............................................................................... ExceptionTests.cpp:: FAILED: {Unknown expression after the reported line} due to unexpected exception with message: unexpected exception ------------------------------------------------------------------------------- Contains string matcher ------------------------------------------------------------------------------- MatchersTests.cpp: ............................................................................... MatchersTests.cpp:: FAILED: CHECK_THAT( testStringForMatching(), Contains( "not there" ) ) with expansion: "this string contains 'abc' as a substring" contains: "not there" ------------------------------------------------------------------------------- Custom exceptions can be translated when testing for nothrow ------------------------------------------------------------------------------- ExceptionTests.cpp: ............................................................................... ExceptionTests.cpp:: FAILED: REQUIRE_NOTHROW( throwCustom() ) due to unexpected exception with message: custom exception - not std ------------------------------------------------------------------------------- Custom exceptions can be translated when testing for throwing as something else ------------------------------------------------------------------------------- ExceptionTests.cpp: ............................................................................... ExceptionTests.cpp:: FAILED: REQUIRE_THROWS_AS( throwCustom(), std::exception ) due to unexpected exception with message: custom exception - not std ------------------------------------------------------------------------------- Custom std-exceptions can be custom translated ------------------------------------------------------------------------------- ExceptionTests.cpp: ............................................................................... ExceptionTests.cpp:: FAILED: due to unexpected exception with message: custom std exception ------------------------------------------------------------------------------- EndsWith string matcher ------------------------------------------------------------------------------- MatchersTests.cpp: ............................................................................... MatchersTests.cpp:: FAILED: CHECK_THAT( testStringForMatching(), EndsWith( "this" ) ) with expansion: "this string contains 'abc' as a substring" ends with: "this" ------------------------------------------------------------------------------- Equality checks that should fail ------------------------------------------------------------------------------- ConditionTests.cpp: ............................................................................... ConditionTests.cpp:: FAILED: CHECK( data.int_seven == 6 ) with expansion: 7 == 6 ConditionTests.cpp:: FAILED: CHECK( data.int_seven == 8 ) with expansion: 7 == 8 ConditionTests.cpp:: FAILED: CHECK( data.int_seven == 0 ) with expansion: 7 == 0 ConditionTests.cpp:: FAILED: CHECK( data.float_nine_point_one == Approx( 9.11f ) ) with expansion: 9.1f == Approx( 9.1099996567 ) ConditionTests.cpp:: FAILED: CHECK( data.float_nine_point_one == Approx( 9.0f ) ) with expansion: 9.1f == Approx( 9.0 ) ConditionTests.cpp:: FAILED: CHECK( data.float_nine_point_one == Approx( 1 ) ) with expansion: 9.1f == Approx( 1.0 ) ConditionTests.cpp:: FAILED: CHECK( data.float_nine_point_one == Approx( 0 ) ) with expansion: 9.1f == Approx( 0.0 ) ConditionTests.cpp:: FAILED: CHECK( data.double_pi == Approx( 3.1415 ) ) with expansion: 3.1415926535 == Approx( 3.1415 ) ConditionTests.cpp:: FAILED: CHECK( data.str_hello == "goodbye" ) with expansion: "hello" == "goodbye" ConditionTests.cpp:: FAILED: CHECK( data.str_hello == "hell" ) with expansion: "hello" == "hell" ConditionTests.cpp:: FAILED: CHECK( data.str_hello == "hello1" ) with expansion: "hello" == "hello1" ConditionTests.cpp:: FAILED: CHECK( data.str_hello.size() == 6 ) with expansion: 5 == 6 ConditionTests.cpp:: FAILED: CHECK( x == Approx( 1.301 ) ) with expansion: 1.3 == Approx( 1.301 ) ------------------------------------------------------------------------------- Equals string matcher ------------------------------------------------------------------------------- MatchersTests.cpp: ............................................................................... MatchersTests.cpp:: FAILED: CHECK_THAT( testStringForMatching(), Equals( "something else" ) ) with expansion: "this string contains 'abc' as a substring" equals: "something else" ------------------------------------------------------------------------------- Expected exceptions that don't throw or unexpected exceptions fail the test ------------------------------------------------------------------------------- ExceptionTests.cpp: ............................................................................... ExceptionTests.cpp:: FAILED: CHECK_THROWS_AS( thisThrows(), std::string ) due to unexpected exception with message: expected exception ExceptionTests.cpp:: FAILED: CHECK_THROWS_AS( thisDoesntThrow(), std::domain_error ) because no exception was thrown where one was expected: ExceptionTests.cpp:: FAILED: CHECK_NOTHROW( thisThrows() ) due to unexpected exception with message: expected exception ------------------------------------------------------------------------------- FAIL aborts the test ------------------------------------------------------------------------------- MessageTests.cpp: ............................................................................... MessageTests.cpp:: FAILED: explicitly with message: This is a failure ------------------------------------------------------------------------------- FAIL does not require an argument ------------------------------------------------------------------------------- MessageTests.cpp: ............................................................................... MessageTests.cpp:: FAILED: ------------------------------------------------------------------------------- FAIL_CHECK does not abort the test ------------------------------------------------------------------------------- MessageTests.cpp: ............................................................................... MessageTests.cpp:: FAILED: explicitly with message: This is a failure MessageTests.cpp:: warning: This message appears in the output ------------------------------------------------------------------------------- INFO and WARN do not abort tests ------------------------------------------------------------------------------- MessageTests.cpp: ............................................................................... MessageTests.cpp:: warning: this is a warning ------------------------------------------------------------------------------- INFO gets logged on failure ------------------------------------------------------------------------------- MessageTests.cpp: ............................................................................... MessageTests.cpp:: FAILED: REQUIRE( a == 1 ) with expansion: 2 == 1 with messages: this message should be logged so should this ------------------------------------------------------------------------------- INFO gets logged on failure, even if captured before successful assertions ------------------------------------------------------------------------------- MessageTests.cpp: ............................................................................... MessageTests.cpp:: FAILED: CHECK( a == 1 ) with expansion: 2 == 1 with messages: this message may be logged later this message should be logged MessageTests.cpp:: FAILED: CHECK( a == 0 ) with expansion: 2 == 0 with messages: this message may be logged later this message should be logged and this, but later ------------------------------------------------------------------------------- Inequality checks that should fail ------------------------------------------------------------------------------- ConditionTests.cpp: ............................................................................... ConditionTests.cpp:: FAILED: CHECK( data.int_seven != 7 ) with expansion: 7 != 7 ConditionTests.cpp:: FAILED: CHECK( data.float_nine_point_one != Approx( 9.1f ) ) with expansion: 9.1f != Approx( 9.1000003815 ) ConditionTests.cpp:: FAILED: CHECK( data.double_pi != Approx( 3.1415926535 ) ) with expansion: 3.1415926535 != Approx( 3.1415926535 ) ConditionTests.cpp:: FAILED: CHECK( data.str_hello != "hello" ) with expansion: "hello" != "hello" ConditionTests.cpp:: FAILED: CHECK( data.str_hello.size() != 5 ) with expansion: 5 != 5 ------------------------------------------------------------------------------- Matchers can be composed with both && and || - failing ------------------------------------------------------------------------------- MatchersTests.cpp: ............................................................................... MatchersTests.cpp:: FAILED: CHECK_THAT( testStringForMatching(), ( Contains( "string" ) || Contains( "different" ) ) && Contains( "random" ) ) with expansion: "this string contains 'abc' as a substring" ( ( contains: "string" or contains: "different" ) and contains: "random" ) ------------------------------------------------------------------------------- Matchers can be negated (Not) with the ! operator - failing ------------------------------------------------------------------------------- MatchersTests.cpp: ............................................................................... MatchersTests.cpp:: FAILED: CHECK_THAT( testStringForMatching(), !Contains( "substring" ) ) with expansion: "this string contains 'abc' as a substring" not contains: "substring" ------------------------------------------------------------------------------- Mismatching exception messages failing the test ------------------------------------------------------------------------------- ExceptionTests.cpp: ............................................................................... ExceptionTests.cpp:: FAILED: REQUIRE_THROWS_WITH( thisThrows(), "should fail" ) with expansion: expected exception ------------------------------------------------------------------------------- Nice descriptive name ------------------------------------------------------------------------------- MiscTests.cpp: ............................................................................... MiscTests.cpp:: warning: This one ran ------------------------------------------------------------------------------- Non-std exceptions can be translated ------------------------------------------------------------------------------- ExceptionTests.cpp: ............................................................................... ExceptionTests.cpp:: FAILED: due to unexpected exception with message: custom exception ------------------------------------------------------------------------------- Ordering comparison checks that should fail ------------------------------------------------------------------------------- ConditionTests.cpp: ............................................................................... ConditionTests.cpp:: FAILED: CHECK( data.int_seven > 7 ) with expansion: 7 > 7 ConditionTests.cpp:: FAILED: CHECK( data.int_seven < 7 ) with expansion: 7 < 7 ConditionTests.cpp:: FAILED: CHECK( data.int_seven > 8 ) with expansion: 7 > 8 ConditionTests.cpp:: FAILED: CHECK( data.int_seven < 6 ) with expansion: 7 < 6 ConditionTests.cpp:: FAILED: CHECK( data.int_seven < 0 ) with expansion: 7 < 0 ConditionTests.cpp:: FAILED: CHECK( data.int_seven < -1 ) with expansion: 7 < -1 ConditionTests.cpp:: FAILED: CHECK( data.int_seven >= 8 ) with expansion: 7 >= 8 ConditionTests.cpp:: FAILED: CHECK( data.int_seven <= 6 ) with expansion: 7 <= 6 ConditionTests.cpp:: FAILED: CHECK( data.float_nine_point_one < 9 ) with expansion: 9.1f < 9 ConditionTests.cpp:: FAILED: CHECK( data.float_nine_point_one > 10 ) with expansion: 9.1f > 10 ConditionTests.cpp:: FAILED: CHECK( data.float_nine_point_one > 9.2 ) with expansion: 9.1f > 9.2 ConditionTests.cpp:: FAILED: CHECK( data.str_hello > "hello" ) with expansion: "hello" > "hello" ConditionTests.cpp:: FAILED: CHECK( data.str_hello < "hello" ) with expansion: "hello" < "hello" ConditionTests.cpp:: FAILED: CHECK( data.str_hello > "hellp" ) with expansion: "hello" > "hellp" ConditionTests.cpp:: FAILED: CHECK( data.str_hello > "z" ) with expansion: "hello" > "z" ConditionTests.cpp:: FAILED: CHECK( data.str_hello < "hellm" ) with expansion: "hello" < "hellm" ConditionTests.cpp:: FAILED: CHECK( data.str_hello < "a" ) with expansion: "hello" < "a" ConditionTests.cpp:: FAILED: CHECK( data.str_hello >= "z" ) with expansion: "hello" >= "z" ConditionTests.cpp:: FAILED: CHECK( data.str_hello <= "a" ) with expansion: "hello" <= "a" ------------------------------------------------------------------------------- Output from all sections is reported one ------------------------------------------------------------------------------- MessageTests.cpp: ............................................................................... MessageTests.cpp:: FAILED: explicitly with message: Message from section one ------------------------------------------------------------------------------- Output from all sections is reported two ------------------------------------------------------------------------------- MessageTests.cpp: ............................................................................... MessageTests.cpp:: FAILED: explicitly with message: Message from section two ------------------------------------------------------------------------------- Pointers can be converted to strings ------------------------------------------------------------------------------- MessageTests.cpp: ............................................................................... MessageTests.cpp:: warning: actual address of p: 0x MessageTests.cpp:: warning: toString(p): 0x ------------------------------------------------------------------------------- Reconstruction should be based on stringification: #914 ------------------------------------------------------------------------------- DecompositionTests.cpp: ............................................................................... DecompositionTests.cpp:: FAILED: CHECK( truthy(false) ) with expansion: Hey, its truthy! ------------------------------------------------------------------------------- SCOPED_INFO is reset for each loop ------------------------------------------------------------------------------- MessageTests.cpp: ............................................................................... MessageTests.cpp:: FAILED: REQUIRE( i < 10 ) with expansion: 10 < 10 with messages: current counter 10 i := 10 A string sent directly to stdout A string sent directly to stderr Write to std::cerr Write to std::clog Interleaved writes to error streams Message from section one Message from section two ------------------------------------------------------------------------------- StartsWith string matcher ------------------------------------------------------------------------------- MatchersTests.cpp: ............................................................................... MatchersTests.cpp:: FAILED: CHECK_THAT( testStringForMatching(), StartsWith( "string" ) ) with expansion: "this string contains 'abc' as a substring" starts with: "string" hello hello ------------------------------------------------------------------------------- Tabs and newlines show in output ------------------------------------------------------------------------------- MiscTests.cpp: ............................................................................... MiscTests.cpp:: FAILED: CHECK( s1 == s2 ) with expansion: "if ($b == 10) { $a = 20; }" == "if ($b == 10) { $a = 20; } " ------------------------------------------------------------------------------- Unexpected exceptions can be translated ------------------------------------------------------------------------------- ExceptionTests.cpp: ............................................................................... ExceptionTests.cpp:: FAILED: due to unexpected exception with message: 3.14 ------------------------------------------------------------------------------- Vector matchers that fail Contains (element) ------------------------------------------------------------------------------- MatchersTests.cpp: ............................................................................... MatchersTests.cpp:: FAILED: CHECK_THAT( v, VectorContains( -1 ) ) with expansion: { 1, 2, 3 } Contains: -1 MatchersTests.cpp:: FAILED: CHECK_THAT( empty, VectorContains( 1 ) ) with expansion: { } Contains: 1 ------------------------------------------------------------------------------- Vector matchers that fail Contains (vector) ------------------------------------------------------------------------------- MatchersTests.cpp: ............................................................................... MatchersTests.cpp:: FAILED: CHECK_THAT( empty, Contains( v) ) with expansion: { } Contains: { 1, 2, 3 } MatchersTests.cpp:: FAILED: CHECK_THAT( v, Contains( v2 ) ) with expansion: { 1, 2, 3 } Contains: { 1, 2, 4 } ------------------------------------------------------------------------------- Vector matchers that fail Equals ------------------------------------------------------------------------------- MatchersTests.cpp: ............................................................................... MatchersTests.cpp:: FAILED: CHECK_THAT( v, Equals( v2 ) ) with expansion: { 1, 2, 3 } Equals: { 1, 2 } MatchersTests.cpp:: FAILED: CHECK_THAT( v2, Equals( v ) ) with expansion: { 1, 2 } Equals: { 1, 2, 3 } MatchersTests.cpp:: FAILED: CHECK_THAT( empty, Equals( v ) ) with expansion: { } Equals: { 1, 2, 3 } MatchersTests.cpp:: FAILED: CHECK_THAT( v, Equals( empty ) ) with expansion: { 1, 2, 3 } Equals: { } ------------------------------------------------------------------------------- When unchecked exceptions are thrown directly they are always failures ------------------------------------------------------------------------------- ExceptionTests.cpp: ............................................................................... ExceptionTests.cpp:: FAILED: due to unexpected exception with message: unexpected exception ------------------------------------------------------------------------------- When unchecked exceptions are thrown during a CHECK the test should continue ------------------------------------------------------------------------------- ExceptionTests.cpp: ............................................................................... ExceptionTests.cpp:: FAILED: CHECK( thisThrows() == 0 ) due to unexpected exception with message: expected exception ------------------------------------------------------------------------------- When unchecked exceptions are thrown during a REQUIRE the test should abort fail ------------------------------------------------------------------------------- ExceptionTests.cpp: ............................................................................... ExceptionTests.cpp:: FAILED: REQUIRE( thisThrows() == 0 ) due to unexpected exception with message: expected exception ------------------------------------------------------------------------------- When unchecked exceptions are thrown from functions they are always failures ------------------------------------------------------------------------------- ExceptionTests.cpp: ............................................................................... ExceptionTests.cpp:: FAILED: CHECK( thisThrows() == 0 ) due to unexpected exception with message: expected exception ------------------------------------------------------------------------------- When unchecked exceptions are thrown from sections they are always failures section name ------------------------------------------------------------------------------- ExceptionTests.cpp: ............................................................................... ExceptionTests.cpp:: FAILED: due to unexpected exception with message: unexpected exception ------------------------------------------------------------------------------- Where the LHS is not a simple value ------------------------------------------------------------------------------- TrickyTests.cpp: ............................................................................... TrickyTests.cpp:: warning: Uncomment the code in this test to check that it gives a sensible compiler error ------------------------------------------------------------------------------- Where there is more to the expression after the RHS ------------------------------------------------------------------------------- TrickyTests.cpp: ............................................................................... TrickyTests.cpp:: warning: Uncomment the code in this test to check that it gives a sensible compiler error ------------------------------------------------------------------------------- checkedElse, failing ------------------------------------------------------------------------------- MiscTests.cpp: ............................................................................... MiscTests.cpp:: FAILED: CHECKED_ELSE( flag ) with expansion: false MiscTests.cpp:: FAILED: REQUIRE( testCheckedElse( false ) ) with expansion: false ------------------------------------------------------------------------------- checkedIf, failing ------------------------------------------------------------------------------- MiscTests.cpp: ............................................................................... MiscTests.cpp:: FAILED: CHECKED_IF( flag ) with expansion: false MiscTests.cpp:: FAILED: REQUIRE( testCheckedIf( false ) ) with expansion: false spanner------------------------------------------------------------------------------- just failure ------------------------------------------------------------------------------- MessageTests.cpp: ............................................................................... MessageTests.cpp:: FAILED: explicitly with message: Previous info should not be seen ------------------------------------------------------------------------------- looped SECTION tests s1 ------------------------------------------------------------------------------- MiscTests.cpp: ............................................................................... MiscTests.cpp:: FAILED: CHECK( b > a ) with expansion: 0 > 1 ------------------------------------------------------------------------------- looped tests ------------------------------------------------------------------------------- MiscTests.cpp: ............................................................................... MiscTests.cpp:: FAILED: CHECK( ( fib[i] % 2 ) == 0 ) with expansion: 1 == 0 with message: Testing if fib[0] (1) is even MiscTests.cpp:: FAILED: CHECK( ( fib[i] % 2 ) == 0 ) with expansion: 1 == 0 with message: Testing if fib[1] (1) is even MiscTests.cpp:: FAILED: CHECK( ( fib[i] % 2 ) == 0 ) with expansion: 1 == 0 with message: Testing if fib[3] (3) is even MiscTests.cpp:: FAILED: CHECK( ( fib[i] % 2 ) == 0 ) with expansion: 1 == 0 with message: Testing if fib[4] (5) is even MiscTests.cpp:: FAILED: CHECK( ( fib[i] % 2 ) == 0 ) with expansion: 1 == 0 with message: Testing if fib[6] (13) is even MiscTests.cpp:: FAILED: CHECK( ( fib[i] % 2 ) == 0 ) with expansion: 1 == 0 with message: Testing if fib[7] (21) is even ------------------------------------------------------------------------------- more nested SECTION tests s1 s2 ------------------------------------------------------------------------------- MiscTests.cpp: ............................................................................... MiscTests.cpp:: FAILED: REQUIRE( a == b ) with expansion: 1 == 2 ------------------------------------------------------------------------------- send a single char to INFO ------------------------------------------------------------------------------- MiscTests.cpp: ............................................................................... MiscTests.cpp:: FAILED: REQUIRE( false ) with message: 3 ------------------------------------------------------------------------------- sends information to INFO ------------------------------------------------------------------------------- MessageTests.cpp: ............................................................................... MessageTests.cpp:: FAILED: REQUIRE( false ) with messages: hi i := 7 ------------------------------------------------------------------------------- string literals of different sizes can be compared ------------------------------------------------------------------------------- TrickyTests.cpp: ............................................................................... TrickyTests.cpp:: FAILED: REQUIRE( std::string( "first" ) == "second" ) with expansion: "first" == "second" =============================================================================== test cases: 171 | 122 passed | 45 failed | 4 failed as expected assertions: 980 | 871 passed | 88 failed | 21 failed as expected catch-1.12.1/projects/SelfTest/Baselines/console.sw.approved.txt000066400000000000000000010454731325474075300246470ustar00rootroot00000000000000 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ is a host application. Run with -? for options ------------------------------------------------------------------------------- # A test name that starts with a # ------------------------------------------------------------------------------- MiscTests.cpp: ............................................................................... MiscTests.cpp:: PASSED: with message: yay ------------------------------------------------------------------------------- #748 - captures with unexpected exceptions outside assertions ------------------------------------------------------------------------------- ExceptionTests.cpp: ............................................................................... ExceptionTests.cpp:: FAILED: due to unexpected exception with messages: answer := 42 expected exception ------------------------------------------------------------------------------- #748 - captures with unexpected exceptions inside REQUIRE_NOTHROW ------------------------------------------------------------------------------- ExceptionTests.cpp: ............................................................................... ExceptionTests.cpp:: FAILED: REQUIRE_NOTHROW( thisThrows() ) due to unexpected exception with messages: answer := 42 expected exception ------------------------------------------------------------------------------- #748 - captures with unexpected exceptions inside REQUIRE_THROWS ------------------------------------------------------------------------------- ExceptionTests.cpp: ............................................................................... ExceptionTests.cpp:: PASSED: REQUIRE_THROWS( thisThrows() ) with message: answer := 42 ------------------------------------------------------------------------------- #809 ------------------------------------------------------------------------------- CompilationTests.cpp: ............................................................................... CompilationTests.cpp:: PASSED: REQUIRE( 42 == f ) with expansion: 42 == {?} ------------------------------------------------------------------------------- #833 ------------------------------------------------------------------------------- CompilationTests.cpp: ............................................................................... CompilationTests.cpp:: PASSED: REQUIRE( a == t ) with expansion: 3 == 3 CompilationTests.cpp:: PASSED: CHECK( a == t ) with expansion: 3 == 3 CompilationTests.cpp:: PASSED: REQUIRE_THROWS( throws_int(true) ) CompilationTests.cpp:: PASSED: CHECK_THROWS_AS( throws_int(true), const int& ) CompilationTests.cpp:: PASSED: REQUIRE_NOTHROW( throws_int(false) ) CompilationTests.cpp:: PASSED: REQUIRE_THAT( "aaa", Catch::EndsWith("aaa") ) with expansion: "aaa" ends with: "aaa" CompilationTests.cpp:: PASSED: REQUIRE( templated_tests(3) ) with expansion: true ------------------------------------------------------------------------------- #835 -- errno should not be touched by Catch ------------------------------------------------------------------------------- MiscTests.cpp: ............................................................................... MiscTests.cpp:: FAILED: CHECK( f() == 0 ) with expansion: 1 == 0 MiscTests.cpp:: PASSED: REQUIRE( errno == 1 ) with expansion: 1 == 1 ------------------------------------------------------------------------------- #961 -- Dynamically created sections should all be reported Looped section 0 ------------------------------------------------------------------------------- MiscTests.cpp: ............................................................................... MiscTests.cpp:: PASSED: with message: Everything is OK ------------------------------------------------------------------------------- #961 -- Dynamically created sections should all be reported Looped section 1 ------------------------------------------------------------------------------- MiscTests.cpp: ............................................................................... MiscTests.cpp:: PASSED: with message: Everything is OK ------------------------------------------------------------------------------- #961 -- Dynamically created sections should all be reported Looped section 2 ------------------------------------------------------------------------------- MiscTests.cpp: ............................................................................... MiscTests.cpp:: PASSED: with message: Everything is OK ------------------------------------------------------------------------------- #961 -- Dynamically created sections should all be reported Looped section 3 ------------------------------------------------------------------------------- MiscTests.cpp: ............................................................................... MiscTests.cpp:: PASSED: with message: Everything is OK ------------------------------------------------------------------------------- #961 -- Dynamically created sections should all be reported Looped section 4 ------------------------------------------------------------------------------- MiscTests.cpp: ............................................................................... MiscTests.cpp:: PASSED: with message: Everything is OK ------------------------------------------------------------------------------- 'Not' checks that should fail ------------------------------------------------------------------------------- ConditionTests.cpp: ............................................................................... ConditionTests.cpp:: FAILED: CHECK( false != false ) ConditionTests.cpp:: FAILED: CHECK( true != true ) ConditionTests.cpp:: FAILED: CHECK( !true ) with expansion: false ConditionTests.cpp:: FAILED: CHECK_FALSE( true ) with expansion: !true ConditionTests.cpp:: FAILED: CHECK( !trueValue ) with expansion: false ConditionTests.cpp:: FAILED: CHECK_FALSE( trueValue ) with expansion: !true ConditionTests.cpp:: FAILED: CHECK( !(1 == 1) ) with expansion: false ConditionTests.cpp:: FAILED: CHECK_FALSE( 1 == 1 ) ------------------------------------------------------------------------------- 'Not' checks that should succeed ------------------------------------------------------------------------------- ConditionTests.cpp: ............................................................................... ConditionTests.cpp:: PASSED: REQUIRE( false == false ) ConditionTests.cpp:: PASSED: REQUIRE( true == true ) ConditionTests.cpp:: PASSED: REQUIRE( !false ) with expansion: true ConditionTests.cpp:: PASSED: REQUIRE_FALSE( false ) with expansion: !false ConditionTests.cpp:: PASSED: REQUIRE( !falseValue ) with expansion: true ConditionTests.cpp:: PASSED: REQUIRE_FALSE( falseValue ) with expansion: !false ConditionTests.cpp:: PASSED: REQUIRE( !(1 == 2) ) with expansion: true ConditionTests.cpp:: PASSED: REQUIRE_FALSE( 1 == 2 ) ------------------------------------------------------------------------------- (unimplemented) static bools can be evaluated compare to true ------------------------------------------------------------------------------- TrickyTests.cpp: ............................................................................... TrickyTests.cpp:: PASSED: REQUIRE( is_true::value == true ) with expansion: true == true TrickyTests.cpp:: PASSED: REQUIRE( true == is_true::value ) with expansion: true == true ------------------------------------------------------------------------------- (unimplemented) static bools can be evaluated compare to false ------------------------------------------------------------------------------- TrickyTests.cpp: ............................................................................... TrickyTests.cpp:: PASSED: REQUIRE( is_true::value == false ) with expansion: false == false TrickyTests.cpp:: PASSED: REQUIRE( false == is_true::value ) with expansion: false == false ------------------------------------------------------------------------------- (unimplemented) static bools can be evaluated negation ------------------------------------------------------------------------------- TrickyTests.cpp: ............................................................................... TrickyTests.cpp:: PASSED: REQUIRE( !is_true::value ) with expansion: true ------------------------------------------------------------------------------- (unimplemented) static bools can be evaluated double negation ------------------------------------------------------------------------------- TrickyTests.cpp: ............................................................................... TrickyTests.cpp:: PASSED: REQUIRE( !!is_true::value ) with expansion: true ------------------------------------------------------------------------------- (unimplemented) static bools can be evaluated direct ------------------------------------------------------------------------------- TrickyTests.cpp: ............................................................................... TrickyTests.cpp:: PASSED: REQUIRE( is_true::value ) with expansion: true TrickyTests.cpp:: PASSED: REQUIRE_FALSE( is_true::value ) with expansion: !false ------------------------------------------------------------------------------- A METHOD_AS_TEST_CASE based test run that fails ------------------------------------------------------------------------------- ClassTests.cpp: ............................................................................... ClassTests.cpp:: FAILED: REQUIRE( s == "world" ) with expansion: "hello" == "world" ------------------------------------------------------------------------------- A METHOD_AS_TEST_CASE based test run that succeeds ------------------------------------------------------------------------------- ClassTests.cpp: ............................................................................... ClassTests.cpp:: PASSED: REQUIRE( s == "hello" ) with expansion: "hello" == "hello" ------------------------------------------------------------------------------- A TEST_CASE_METHOD based test run that fails ------------------------------------------------------------------------------- ClassTests.cpp: ............................................................................... ClassTests.cpp:: FAILED: REQUIRE( m_a == 2 ) with expansion: 1 == 2 ------------------------------------------------------------------------------- A TEST_CASE_METHOD based test run that succeeds ------------------------------------------------------------------------------- ClassTests.cpp: ............................................................................... ClassTests.cpp:: PASSED: REQUIRE( m_a == 1 ) with expansion: 1 == 1 ------------------------------------------------------------------------------- A couple of nested sections followed by a failure Outer Inner ------------------------------------------------------------------------------- MiscTests.cpp: ............................................................................... MiscTests.cpp:: PASSED: with message: that's not flying - that's failing in style ------------------------------------------------------------------------------- A couple of nested sections followed by a failure ------------------------------------------------------------------------------- MiscTests.cpp: ............................................................................... MiscTests.cpp:: FAILED: explicitly with message: to infinity and beyond ------------------------------------------------------------------------------- A failing expression with a non streamable type is still captured ------------------------------------------------------------------------------- TrickyTests.cpp: ............................................................................... TrickyTests.cpp:: FAILED: CHECK( &o1 == &o2 ) with expansion: 0x == 0x TrickyTests.cpp:: FAILED: CHECK( o1 == o2 ) with expansion: {?} == {?} ------------------------------------------------------------------------------- Absolute margin ------------------------------------------------------------------------------- ApproxTests.cpp: ............................................................................... ApproxTests.cpp:: PASSED: REQUIRE( 104.0 != Approx(100.0) ) with expansion: 104.0 != Approx( 100.0 ) ApproxTests.cpp:: PASSED: REQUIRE( 104.0 == Approx(100.0).margin(5) ) with expansion: 104.0 == Approx( 100.0 ) ApproxTests.cpp:: PASSED: REQUIRE( 104.0 == Approx(100.0).margin(4) ) with expansion: 104.0 == Approx( 100.0 ) ApproxTests.cpp:: PASSED: REQUIRE( 104.0 != Approx(100.0).margin(3) ) with expansion: 104.0 != Approx( 100.0 ) ApproxTests.cpp:: PASSED: REQUIRE( 100.3 != Approx(100.0) ) with expansion: 100.3 != Approx( 100.0 ) ApproxTests.cpp:: PASSED: REQUIRE( 100.3 == Approx(100.0).margin(0.5) ) with expansion: 100.3 == Approx( 100.0 ) ------------------------------------------------------------------------------- AllOf matcher ------------------------------------------------------------------------------- MatchersTests.cpp: ............................................................................... MatchersTests.cpp:: PASSED: CHECK_THAT( testStringForMatching(), AllOf( Catch::Contains( "string" ), Catch::Contains( "abc" ) ) ) with expansion: "this string contains 'abc' as a substring" ( contains: "string" and contains: "abc" ) ------------------------------------------------------------------------------- An expression with side-effects should only be evaluated once ------------------------------------------------------------------------------- TrickyTests.cpp: ............................................................................... TrickyTests.cpp:: PASSED: REQUIRE( i++ == 7 ) with expansion: 7 == 7 TrickyTests.cpp:: PASSED: REQUIRE( i++ == 8 ) with expansion: 8 == 8 ------------------------------------------------------------------------------- An unchecked exception reports the line of the last assertion ------------------------------------------------------------------------------- ExceptionTests.cpp: ............................................................................... ExceptionTests.cpp:: PASSED: CHECK( 1 == 1 ) ExceptionTests.cpp:: FAILED: {Unknown expression after the reported line} due to unexpected exception with message: unexpected exception ------------------------------------------------------------------------------- Anonymous test case 1 ------------------------------------------------------------------------------- VariadicMacrosTests.cpp: ............................................................................... VariadicMacrosTests.cpp:: PASSED: with message: anonymous test case ------------------------------------------------------------------------------- AnyOf matcher ------------------------------------------------------------------------------- MatchersTests.cpp: ............................................................................... MatchersTests.cpp:: PASSED: CHECK_THAT( testStringForMatching(), AnyOf( Catch::Contains( "string" ), Catch::Contains( "not there" ) ) ) with expansion: "this string contains 'abc' as a substring" ( contains: "string" or contains: "not there" ) MatchersTests.cpp:: PASSED: CHECK_THAT( testStringForMatching(), AnyOf( Catch::Contains( "not there" ), Catch::Contains( "string" ) ) ) with expansion: "this string contains 'abc' as a substring" ( contains: "not there" or contains: "string" ) ------------------------------------------------------------------------------- Approx with exactly-representable margin ------------------------------------------------------------------------------- ApproxTests.cpp: ............................................................................... ApproxTests.cpp:: PASSED: CHECK( 0.25f == Approx(0.0f).margin(0.25f) ) with expansion: 0.25f == Approx( 0.0 ) ApproxTests.cpp:: PASSED: CHECK( 0.0f == Approx(0.25f).margin(0.25f) ) with expansion: 0.0f == Approx( 0.25 ) ApproxTests.cpp:: PASSED: CHECK( 0.5f == Approx(0.25f).margin(0.25f) ) with expansion: 0.5f == Approx( 0.25 ) ApproxTests.cpp:: PASSED: CHECK( 245.0f == Approx(245.25f).margin(0.25f) ) with expansion: 245.0f == Approx( 245.25 ) ApproxTests.cpp:: PASSED: CHECK( 245.5f == Approx(245.25f).margin(0.25f) ) with expansion: 245.5f == Approx( 245.25 ) ------------------------------------------------------------------------------- Approximate PI ------------------------------------------------------------------------------- ApproxTests.cpp: ............................................................................... ApproxTests.cpp:: PASSED: REQUIRE( divide( 22, 7 ) == Approx( 3.141 ).epsilon( 0.001 ) ) with expansion: 3.1428571429 == Approx( 3.141 ) ApproxTests.cpp:: PASSED: REQUIRE( divide( 22, 7 ) != Approx( 3.141 ).epsilon( 0.0001 ) ) with expansion: 3.1428571429 != Approx( 3.141 ) ------------------------------------------------------------------------------- Approximate comparisons with different epsilons ------------------------------------------------------------------------------- ApproxTests.cpp: ............................................................................... ApproxTests.cpp:: PASSED: REQUIRE( d != Approx( 1.231 ) ) with expansion: 1.23 != Approx( 1.231 ) ApproxTests.cpp:: PASSED: REQUIRE( d == Approx( 1.231 ).epsilon( 0.1 ) ) with expansion: 1.23 == Approx( 1.231 ) ------------------------------------------------------------------------------- Approximate comparisons with floats ------------------------------------------------------------------------------- ApproxTests.cpp: ............................................................................... ApproxTests.cpp:: PASSED: REQUIRE( 1.23f == Approx( 1.23f ) ) with expansion: 1.23f == Approx( 1.2300000191 ) ApproxTests.cpp:: PASSED: REQUIRE( 0.0f == Approx( 0.0f ) ) with expansion: 0.0f == Approx( 0.0 ) ------------------------------------------------------------------------------- Approximate comparisons with ints ------------------------------------------------------------------------------- ApproxTests.cpp: ............................................................................... ApproxTests.cpp:: PASSED: REQUIRE( 1 == Approx( 1 ) ) with expansion: 1 == Approx( 1.0 ) ApproxTests.cpp:: PASSED: REQUIRE( 0 == Approx( 0 ) ) with expansion: 0 == Approx( 0.0 ) ------------------------------------------------------------------------------- Approximate comparisons with mixed numeric types ------------------------------------------------------------------------------- ApproxTests.cpp: ............................................................................... ApproxTests.cpp:: PASSED: REQUIRE( 1.0f == Approx( 1 ) ) with expansion: 1.0f == Approx( 1.0 ) ApproxTests.cpp:: PASSED: REQUIRE( 0 == Approx( dZero) ) with expansion: 0 == Approx( 0.0 ) ApproxTests.cpp:: PASSED: REQUIRE( 0 == Approx( dSmall ).epsilon( 0.001 ) ) with expansion: 0 == Approx( 0.00001 ) ApproxTests.cpp:: PASSED: REQUIRE( 1.234f == Approx( dMedium ) ) with expansion: 1.234f == Approx( 1.234 ) ApproxTests.cpp:: PASSED: REQUIRE( dMedium == Approx( 1.234f ) ) with expansion: 1.234 == Approx( 1.2339999676 ) ------------------------------------------------------------------------------- Assertions then sections ------------------------------------------------------------------------------- TrickyTests.cpp: ............................................................................... TrickyTests.cpp:: PASSED: REQUIRE( Catch::alwaysTrue() ) with expansion: true ------------------------------------------------------------------------------- Assertions then sections A section ------------------------------------------------------------------------------- TrickyTests.cpp: ............................................................................... TrickyTests.cpp:: PASSED: REQUIRE( Catch::alwaysTrue() ) with expansion: true ------------------------------------------------------------------------------- Assertions then sections A section Another section ------------------------------------------------------------------------------- TrickyTests.cpp: ............................................................................... TrickyTests.cpp:: PASSED: REQUIRE( Catch::alwaysTrue() ) with expansion: true ------------------------------------------------------------------------------- Assertions then sections ------------------------------------------------------------------------------- TrickyTests.cpp: ............................................................................... TrickyTests.cpp:: PASSED: REQUIRE( Catch::alwaysTrue() ) with expansion: true ------------------------------------------------------------------------------- Assertions then sections A section ------------------------------------------------------------------------------- TrickyTests.cpp: ............................................................................... TrickyTests.cpp:: PASSED: REQUIRE( Catch::alwaysTrue() ) with expansion: true ------------------------------------------------------------------------------- Assertions then sections A section Another other section ------------------------------------------------------------------------------- TrickyTests.cpp: ............................................................................... TrickyTests.cpp:: PASSED: REQUIRE( Catch::alwaysTrue() ) with expansion: true ------------------------------------------------------------------------------- Capture and info messages Capture should stringify like assertions ------------------------------------------------------------------------------- ToStringGeneralTests.cpp: ............................................................................... ToStringGeneralTests.cpp:: PASSED: REQUIRE( true ) with message: i := 2 ------------------------------------------------------------------------------- Capture and info messages Info should NOT stringify the way assertions do ------------------------------------------------------------------------------- ToStringGeneralTests.cpp: ............................................................................... ToStringGeneralTests.cpp:: PASSED: REQUIRE( true ) with message: 3 ------------------------------------------------------------------------------- Character pretty printing Specifically escaped ------------------------------------------------------------------------------- ToStringGeneralTests.cpp: ............................................................................... ToStringGeneralTests.cpp:: PASSED: CHECK( tab == '\t' ) with expansion: '\t' == '\t' ToStringGeneralTests.cpp:: PASSED: CHECK( newline == '\n' ) with expansion: '\n' == '\n' ToStringGeneralTests.cpp:: PASSED: CHECK( carr_return == '\r' ) with expansion: '\r' == '\r' ToStringGeneralTests.cpp:: PASSED: CHECK( form_feed == '\f' ) with expansion: '\f' == '\f' ------------------------------------------------------------------------------- Character pretty printing General chars ------------------------------------------------------------------------------- ToStringGeneralTests.cpp: ............................................................................... ToStringGeneralTests.cpp:: PASSED: CHECK( space == ' ' ) with expansion: ' ' == ' ' ToStringGeneralTests.cpp:: PASSED: REQUIRE( c == chars[i] ) with expansion: 'a' == 'a' ToStringGeneralTests.cpp:: PASSED: REQUIRE( c == chars[i] ) with expansion: 'z' == 'z' ToStringGeneralTests.cpp:: PASSED: REQUIRE( c == chars[i] ) with expansion: 'A' == 'A' ToStringGeneralTests.cpp:: PASSED: REQUIRE( c == chars[i] ) with expansion: 'Z' == 'Z' ------------------------------------------------------------------------------- Character pretty printing Low ASCII ------------------------------------------------------------------------------- ToStringGeneralTests.cpp: ............................................................................... ToStringGeneralTests.cpp:: PASSED: CHECK( null_terminator == '\0' ) with expansion: 0 == 0 ToStringGeneralTests.cpp:: PASSED: REQUIRE( c == i ) with expansion: 2 == 2 ToStringGeneralTests.cpp:: PASSED: REQUIRE( c == i ) with expansion: 3 == 3 ToStringGeneralTests.cpp:: PASSED: REQUIRE( c == i ) with expansion: 4 == 4 ToStringGeneralTests.cpp:: PASSED: REQUIRE( c == i ) with expansion: 5 == 5 ------------------------------------------------------------------------------- Comparing function pointers ------------------------------------------------------------------------------- TrickyTests.cpp: ............................................................................... TrickyTests.cpp:: PASSED: REQUIRE( a ) with expansion: 0x TrickyTests.cpp:: PASSED: REQUIRE( a == &foo ) with expansion: 0x == 0x ------------------------------------------------------------------------------- Comparing member function pointers ------------------------------------------------------------------------------- TrickyTests.cpp: ............................................................................... TrickyTests.cpp:: PASSED: CHECK( m == &S::f ) with expansion: 0x == 0x ------------------------------------------------------------------------------- Comparisons between ints where one side is computed ------------------------------------------------------------------------------- ConditionTests.cpp: ............................................................................... ConditionTests.cpp:: PASSED: CHECK( 54 == 6*9 ) with expansion: 54 == 54 ------------------------------------------------------------------------------- Comparisons between unsigned ints and negative signed ints match c++ standard behaviour ------------------------------------------------------------------------------- ConditionTests.cpp: ............................................................................... ConditionTests.cpp:: PASSED: CHECK( ( -1 > 2u ) ) with expansion: true ConditionTests.cpp:: PASSED: CHECK( -1 > 2u ) with expansion: -1 > 2 ConditionTests.cpp:: PASSED: CHECK( ( 2u < -1 ) ) with expansion: true ConditionTests.cpp:: PASSED: CHECK( 2u < -1 ) with expansion: 2 < -1 ConditionTests.cpp:: PASSED: CHECK( ( minInt > 2u ) ) with expansion: true ConditionTests.cpp:: PASSED: CHECK( minInt > 2u ) with expansion: -2147483648 > 2 ------------------------------------------------------------------------------- Comparisons with int literals don't warn when mixing signed/ unsigned ------------------------------------------------------------------------------- ConditionTests.cpp: ............................................................................... ConditionTests.cpp:: PASSED: REQUIRE( i == 1 ) with expansion: 1 == 1 ConditionTests.cpp:: PASSED: REQUIRE( ui == 2 ) with expansion: 2 == 2 ConditionTests.cpp:: PASSED: REQUIRE( l == 3 ) with expansion: 3 == 3 ConditionTests.cpp:: PASSED: REQUIRE( ul == 4 ) with expansion: 4 == 4 ConditionTests.cpp:: PASSED: REQUIRE( c == 5 ) with expansion: 5 == 5 ConditionTests.cpp:: PASSED: REQUIRE( uc == 6 ) with expansion: 6 == 6 ConditionTests.cpp:: PASSED: REQUIRE( 1 == i ) with expansion: 1 == 1 ConditionTests.cpp:: PASSED: REQUIRE( 2 == ui ) with expansion: 2 == 2 ConditionTests.cpp:: PASSED: REQUIRE( 3 == l ) with expansion: 3 == 3 ConditionTests.cpp:: PASSED: REQUIRE( 4 == ul ) with expansion: 4 == 4 ConditionTests.cpp:: PASSED: REQUIRE( 5 == c ) with expansion: 5 == 5 ConditionTests.cpp:: PASSED: REQUIRE( 6 == uc ) with expansion: 6 == 6 ConditionTests.cpp:: PASSED: REQUIRE( (std::numeric_limits::max)() > ul ) with expansion: 18446744073709551615 (0x) > 4 ------------------------------------------------------------------------------- Contains string matcher ------------------------------------------------------------------------------- MatchersTests.cpp: ............................................................................... MatchersTests.cpp:: FAILED: CHECK_THAT( testStringForMatching(), Contains( "not there" ) ) with expansion: "this string contains 'abc' as a substring" contains: "not there" ------------------------------------------------------------------------------- Custom exceptions can be translated when testing for nothrow ------------------------------------------------------------------------------- ExceptionTests.cpp: ............................................................................... ExceptionTests.cpp:: FAILED: REQUIRE_NOTHROW( throwCustom() ) due to unexpected exception with message: custom exception - not std ------------------------------------------------------------------------------- Custom exceptions can be translated when testing for throwing as something else ------------------------------------------------------------------------------- ExceptionTests.cpp: ............................................................................... ExceptionTests.cpp:: FAILED: REQUIRE_THROWS_AS( throwCustom(), std::exception ) due to unexpected exception with message: custom exception - not std ------------------------------------------------------------------------------- Custom std-exceptions can be custom translated ------------------------------------------------------------------------------- ExceptionTests.cpp: ............................................................................... ExceptionTests.cpp:: FAILED: due to unexpected exception with message: custom std exception ------------------------------------------------------------------------------- Demonstrate that a non-const == is not used ------------------------------------------------------------------------------- TrickyTests.cpp: ............................................................................... TrickyTests.cpp:: PASSED: REQUIRE( t == 1u ) with expansion: {?} == 1 ------------------------------------------------------------------------------- EndsWith string matcher ------------------------------------------------------------------------------- MatchersTests.cpp: ............................................................................... MatchersTests.cpp:: FAILED: CHECK_THAT( testStringForMatching(), EndsWith( "this" ) ) with expansion: "this string contains 'abc' as a substring" ends with: "this" ------------------------------------------------------------------------------- Equality checks that should fail ------------------------------------------------------------------------------- ConditionTests.cpp: ............................................................................... ConditionTests.cpp:: FAILED: CHECK( data.int_seven == 6 ) with expansion: 7 == 6 ConditionTests.cpp:: FAILED: CHECK( data.int_seven == 8 ) with expansion: 7 == 8 ConditionTests.cpp:: FAILED: CHECK( data.int_seven == 0 ) with expansion: 7 == 0 ConditionTests.cpp:: FAILED: CHECK( data.float_nine_point_one == Approx( 9.11f ) ) with expansion: 9.1f == Approx( 9.1099996567 ) ConditionTests.cpp:: FAILED: CHECK( data.float_nine_point_one == Approx( 9.0f ) ) with expansion: 9.1f == Approx( 9.0 ) ConditionTests.cpp:: FAILED: CHECK( data.float_nine_point_one == Approx( 1 ) ) with expansion: 9.1f == Approx( 1.0 ) ConditionTests.cpp:: FAILED: CHECK( data.float_nine_point_one == Approx( 0 ) ) with expansion: 9.1f == Approx( 0.0 ) ConditionTests.cpp:: FAILED: CHECK( data.double_pi == Approx( 3.1415 ) ) with expansion: 3.1415926535 == Approx( 3.1415 ) ConditionTests.cpp:: FAILED: CHECK( data.str_hello == "goodbye" ) with expansion: "hello" == "goodbye" ConditionTests.cpp:: FAILED: CHECK( data.str_hello == "hell" ) with expansion: "hello" == "hell" ConditionTests.cpp:: FAILED: CHECK( data.str_hello == "hello1" ) with expansion: "hello" == "hello1" ConditionTests.cpp:: FAILED: CHECK( data.str_hello.size() == 6 ) with expansion: 5 == 6 ConditionTests.cpp:: FAILED: CHECK( x == Approx( 1.301 ) ) with expansion: 1.3 == Approx( 1.301 ) ------------------------------------------------------------------------------- Equality checks that should succeed ------------------------------------------------------------------------------- ConditionTests.cpp: ............................................................................... ConditionTests.cpp:: PASSED: REQUIRE( data.int_seven == 7 ) with expansion: 7 == 7 ConditionTests.cpp:: PASSED: REQUIRE( data.float_nine_point_one == Approx( 9.1f ) ) with expansion: 9.1f == Approx( 9.1000003815 ) ConditionTests.cpp:: PASSED: REQUIRE( data.double_pi == Approx( 3.1415926535 ) ) with expansion: 3.1415926535 == Approx( 3.1415926535 ) ConditionTests.cpp:: PASSED: REQUIRE( data.str_hello == "hello" ) with expansion: "hello" == "hello" ConditionTests.cpp:: PASSED: REQUIRE( "hello" == data.str_hello ) with expansion: "hello" == "hello" ConditionTests.cpp:: PASSED: REQUIRE( data.str_hello.size() == 5 ) with expansion: 5 == 5 ConditionTests.cpp:: PASSED: REQUIRE( x == Approx( 1.3 ) ) with expansion: 1.3 == Approx( 1.3 ) ------------------------------------------------------------------------------- Equals ------------------------------------------------------------------------------- MatchersTests.cpp: ............................................................................... MatchersTests.cpp:: PASSED: CHECK_THAT( testStringForMatching(), Equals( "this string contains 'abc' as a substring" ) ) with expansion: "this string contains 'abc' as a substring" equals: "this string contains 'abc' as a substring" ------------------------------------------------------------------------------- Equals string matcher ------------------------------------------------------------------------------- MatchersTests.cpp: ............................................................................... MatchersTests.cpp:: FAILED: CHECK_THAT( testStringForMatching(), Equals( "something else" ) ) with expansion: "this string contains 'abc' as a substring" equals: "something else" ------------------------------------------------------------------------------- Exception messages can be tested for exact match ------------------------------------------------------------------------------- ExceptionTests.cpp: ............................................................................... ExceptionTests.cpp:: PASSED: REQUIRE_THROWS_WITH( thisThrows(), "expected exception" ) ------------------------------------------------------------------------------- Exception messages can be tested for different case ------------------------------------------------------------------------------- ExceptionTests.cpp: ............................................................................... ExceptionTests.cpp:: PASSED: REQUIRE_THROWS_WITH( thisThrows(), Equals( "expecteD Exception", Catch::CaseSensitive::No ) ) ------------------------------------------------------------------------------- Exception messages can be tested for wildcarded ------------------------------------------------------------------------------- ExceptionTests.cpp: ............................................................................... ExceptionTests.cpp:: PASSED: REQUIRE_THROWS_WITH( thisThrows(), StartsWith( "expected" ) ) ExceptionTests.cpp:: PASSED: REQUIRE_THROWS_WITH( thisThrows(), EndsWith( "exception" ) ) ExceptionTests.cpp:: PASSED: REQUIRE_THROWS_WITH( thisThrows(), Contains( "except" ) ) ExceptionTests.cpp:: PASSED: REQUIRE_THROWS_WITH( thisThrows(), Contains( "exCept", Catch::CaseSensitive::No ) ) ------------------------------------------------------------------------------- Expected exceptions that don't throw or unexpected exceptions fail the test ------------------------------------------------------------------------------- ExceptionTests.cpp: ............................................................................... ExceptionTests.cpp:: FAILED: CHECK_THROWS_AS( thisThrows(), std::string ) due to unexpected exception with message: expected exception ExceptionTests.cpp:: FAILED: CHECK_THROWS_AS( thisDoesntThrow(), std::domain_error ) because no exception was thrown where one was expected: ExceptionTests.cpp:: FAILED: CHECK_NOTHROW( thisThrows() ) due to unexpected exception with message: expected exception ------------------------------------------------------------------------------- FAIL aborts the test ------------------------------------------------------------------------------- MessageTests.cpp: ............................................................................... MessageTests.cpp:: FAILED: explicitly with message: This is a failure ------------------------------------------------------------------------------- FAIL does not require an argument ------------------------------------------------------------------------------- MessageTests.cpp: ............................................................................... MessageTests.cpp:: FAILED: ------------------------------------------------------------------------------- FAIL_CHECK does not abort the test ------------------------------------------------------------------------------- MessageTests.cpp: ............................................................................... MessageTests.cpp:: FAILED: explicitly with message: This is a failure MessageTests.cpp:: warning: This message appears in the output ------------------------------------------------------------------------------- Factorials are computed ------------------------------------------------------------------------------- MiscTests.cpp: ............................................................................... MiscTests.cpp:: PASSED: REQUIRE( Factorial(0) == 1 ) with expansion: 1 == 1 MiscTests.cpp:: PASSED: REQUIRE( Factorial(1) == 1 ) with expansion: 1 == 1 MiscTests.cpp:: PASSED: REQUIRE( Factorial(2) == 2 ) with expansion: 2 == 2 MiscTests.cpp:: PASSED: REQUIRE( Factorial(3) == 6 ) with expansion: 6 == 6 MiscTests.cpp:: PASSED: REQUIRE( Factorial(10) == 3628800 ) with expansion: 3628800 (0x) == 3628800 (0x) ------------------------------------------------------------------------------- Generator over a range of pairs ------------------------------------------------------------------------------- GeneratorTests.cpp: ............................................................................... GeneratorTests.cpp:: PASSED: CATCH_REQUIRE( i->first == i->second-1 ) with expansion: 0 == 0 ------------------------------------------------------------------------------- Generator over a range of pairs ------------------------------------------------------------------------------- GeneratorTests.cpp: ............................................................................... GeneratorTests.cpp:: PASSED: CATCH_REQUIRE( i->first == i->second-1 ) with expansion: 2 == 2 ------------------------------------------------------------------------------- Generators over two ranges ------------------------------------------------------------------------------- GeneratorTests.cpp: ............................................................................... GeneratorTests.cpp:: PASSED: CATCH_REQUIRE( multiply( i, 2 ) == i*2 ) with expansion: 2 == 2 GeneratorTests.cpp:: PASSED: CATCH_REQUIRE( multiply( j, 2 ) == j*2 ) with expansion: 200 == 200 ------------------------------------------------------------------------------- Generators over two ranges ------------------------------------------------------------------------------- GeneratorTests.cpp: ............................................................................... GeneratorTests.cpp:: PASSED: CATCH_REQUIRE( multiply( i, 2 ) == i*2 ) with expansion: 4 == 4 GeneratorTests.cpp:: PASSED: CATCH_REQUIRE( multiply( j, 2 ) == j*2 ) with expansion: 200 == 200 ------------------------------------------------------------------------------- Generators over two ranges ------------------------------------------------------------------------------- GeneratorTests.cpp: ............................................................................... GeneratorTests.cpp:: PASSED: CATCH_REQUIRE( multiply( i, 2 ) == i*2 ) with expansion: 6 == 6 GeneratorTests.cpp:: PASSED: CATCH_REQUIRE( multiply( j, 2 ) == j*2 ) with expansion: 200 == 200 ------------------------------------------------------------------------------- Generators over two ranges ------------------------------------------------------------------------------- GeneratorTests.cpp: ............................................................................... GeneratorTests.cpp:: PASSED: CATCH_REQUIRE( multiply( i, 2 ) == i*2 ) with expansion: 8 == 8 GeneratorTests.cpp:: PASSED: CATCH_REQUIRE( multiply( j, 2 ) == j*2 ) with expansion: 200 == 200 ------------------------------------------------------------------------------- Generators over two ranges ------------------------------------------------------------------------------- GeneratorTests.cpp: ............................................................................... GeneratorTests.cpp:: PASSED: CATCH_REQUIRE( multiply( i, 2 ) == i*2 ) with expansion: 10 == 10 GeneratorTests.cpp:: PASSED: CATCH_REQUIRE( multiply( j, 2 ) == j*2 ) with expansion: 200 == 200 ------------------------------------------------------------------------------- Generators over two ranges ------------------------------------------------------------------------------- GeneratorTests.cpp: ............................................................................... GeneratorTests.cpp:: PASSED: CATCH_REQUIRE( multiply( i, 2 ) == i*2 ) with expansion: 30 == 30 GeneratorTests.cpp:: PASSED: CATCH_REQUIRE( multiply( j, 2 ) == j*2 ) with expansion: 200 == 200 ------------------------------------------------------------------------------- Generators over two ranges ------------------------------------------------------------------------------- GeneratorTests.cpp: ............................................................................... GeneratorTests.cpp:: PASSED: CATCH_REQUIRE( multiply( i, 2 ) == i*2 ) with expansion: 40 == 40 GeneratorTests.cpp:: PASSED: CATCH_REQUIRE( multiply( j, 2 ) == j*2 ) with expansion: 200 == 200 ------------------------------------------------------------------------------- Generators over two ranges ------------------------------------------------------------------------------- GeneratorTests.cpp: ............................................................................... GeneratorTests.cpp:: PASSED: CATCH_REQUIRE( multiply( i, 2 ) == i*2 ) with expansion: 42 == 42 GeneratorTests.cpp:: PASSED: CATCH_REQUIRE( multiply( j, 2 ) == j*2 ) with expansion: 200 == 200 ------------------------------------------------------------------------------- Generators over two ranges ------------------------------------------------------------------------------- GeneratorTests.cpp: ............................................................................... GeneratorTests.cpp:: PASSED: CATCH_REQUIRE( multiply( i, 2 ) == i*2 ) with expansion: 72 == 72 GeneratorTests.cpp:: PASSED: CATCH_REQUIRE( multiply( j, 2 ) == j*2 ) with expansion: 200 == 200 ------------------------------------------------------------------------------- Generators over two ranges ------------------------------------------------------------------------------- GeneratorTests.cpp: ............................................................................... GeneratorTests.cpp:: PASSED: CATCH_REQUIRE( multiply( i, 2 ) == i*2 ) with expansion: 2 == 2 GeneratorTests.cpp:: PASSED: CATCH_REQUIRE( multiply( j, 2 ) == j*2 ) with expansion: 202 == 202 ------------------------------------------------------------------------------- Generators over two ranges ------------------------------------------------------------------------------- GeneratorTests.cpp: ............................................................................... GeneratorTests.cpp:: PASSED: CATCH_REQUIRE( multiply( i, 2 ) == i*2 ) with expansion: 4 == 4 GeneratorTests.cpp:: PASSED: CATCH_REQUIRE( multiply( j, 2 ) == j*2 ) with expansion: 202 == 202 ------------------------------------------------------------------------------- Generators over two ranges ------------------------------------------------------------------------------- GeneratorTests.cpp: ............................................................................... GeneratorTests.cpp:: PASSED: CATCH_REQUIRE( multiply( i, 2 ) == i*2 ) with expansion: 6 == 6 GeneratorTests.cpp:: PASSED: CATCH_REQUIRE( multiply( j, 2 ) == j*2 ) with expansion: 202 == 202 ------------------------------------------------------------------------------- Generators over two ranges ------------------------------------------------------------------------------- GeneratorTests.cpp: ............................................................................... GeneratorTests.cpp:: PASSED: CATCH_REQUIRE( multiply( i, 2 ) == i*2 ) with expansion: 8 == 8 GeneratorTests.cpp:: PASSED: CATCH_REQUIRE( multiply( j, 2 ) == j*2 ) with expansion: 202 == 202 ------------------------------------------------------------------------------- Generators over two ranges ------------------------------------------------------------------------------- GeneratorTests.cpp: ............................................................................... GeneratorTests.cpp:: PASSED: CATCH_REQUIRE( multiply( i, 2 ) == i*2 ) with expansion: 10 == 10 GeneratorTests.cpp:: PASSED: CATCH_REQUIRE( multiply( j, 2 ) == j*2 ) with expansion: 202 == 202 ------------------------------------------------------------------------------- Generators over two ranges ------------------------------------------------------------------------------- GeneratorTests.cpp: ............................................................................... GeneratorTests.cpp:: PASSED: CATCH_REQUIRE( multiply( i, 2 ) == i*2 ) with expansion: 30 == 30 GeneratorTests.cpp:: PASSED: CATCH_REQUIRE( multiply( j, 2 ) == j*2 ) with expansion: 202 == 202 ------------------------------------------------------------------------------- Generators over two ranges ------------------------------------------------------------------------------- GeneratorTests.cpp: ............................................................................... GeneratorTests.cpp:: PASSED: CATCH_REQUIRE( multiply( i, 2 ) == i*2 ) with expansion: 40 == 40 GeneratorTests.cpp:: PASSED: CATCH_REQUIRE( multiply( j, 2 ) == j*2 ) with expansion: 202 == 202 ------------------------------------------------------------------------------- Generators over two ranges ------------------------------------------------------------------------------- GeneratorTests.cpp: ............................................................................... GeneratorTests.cpp:: PASSED: CATCH_REQUIRE( multiply( i, 2 ) == i*2 ) with expansion: 42 == 42 GeneratorTests.cpp:: PASSED: CATCH_REQUIRE( multiply( j, 2 ) == j*2 ) with expansion: 202 == 202 ------------------------------------------------------------------------------- Generators over two ranges ------------------------------------------------------------------------------- GeneratorTests.cpp: ............................................................................... GeneratorTests.cpp:: PASSED: CATCH_REQUIRE( multiply( i, 2 ) == i*2 ) with expansion: 72 == 72 GeneratorTests.cpp:: PASSED: CATCH_REQUIRE( multiply( j, 2 ) == j*2 ) with expansion: 202 == 202 ------------------------------------------------------------------------------- Generators over two ranges ------------------------------------------------------------------------------- GeneratorTests.cpp: ............................................................................... GeneratorTests.cpp:: PASSED: CATCH_REQUIRE( multiply( i, 2 ) == i*2 ) with expansion: 2 == 2 GeneratorTests.cpp:: PASSED: CATCH_REQUIRE( multiply( j, 2 ) == j*2 ) with expansion: 204 == 204 ------------------------------------------------------------------------------- Generators over two ranges ------------------------------------------------------------------------------- GeneratorTests.cpp: ............................................................................... GeneratorTests.cpp:: PASSED: CATCH_REQUIRE( multiply( i, 2 ) == i*2 ) with expansion: 4 == 4 GeneratorTests.cpp:: PASSED: CATCH_REQUIRE( multiply( j, 2 ) == j*2 ) with expansion: 204 == 204 ------------------------------------------------------------------------------- Generators over two ranges ------------------------------------------------------------------------------- GeneratorTests.cpp: ............................................................................... GeneratorTests.cpp:: PASSED: CATCH_REQUIRE( multiply( i, 2 ) == i*2 ) with expansion: 6 == 6 GeneratorTests.cpp:: PASSED: CATCH_REQUIRE( multiply( j, 2 ) == j*2 ) with expansion: 204 == 204 ------------------------------------------------------------------------------- Generators over two ranges ------------------------------------------------------------------------------- GeneratorTests.cpp: ............................................................................... GeneratorTests.cpp:: PASSED: CATCH_REQUIRE( multiply( i, 2 ) == i*2 ) with expansion: 8 == 8 GeneratorTests.cpp:: PASSED: CATCH_REQUIRE( multiply( j, 2 ) == j*2 ) with expansion: 204 == 204 ------------------------------------------------------------------------------- Generators over two ranges ------------------------------------------------------------------------------- GeneratorTests.cpp: ............................................................................... GeneratorTests.cpp:: PASSED: CATCH_REQUIRE( multiply( i, 2 ) == i*2 ) with expansion: 10 == 10 GeneratorTests.cpp:: PASSED: CATCH_REQUIRE( multiply( j, 2 ) == j*2 ) with expansion: 204 == 204 ------------------------------------------------------------------------------- Generators over two ranges ------------------------------------------------------------------------------- GeneratorTests.cpp: ............................................................................... GeneratorTests.cpp:: PASSED: CATCH_REQUIRE( multiply( i, 2 ) == i*2 ) with expansion: 30 == 30 GeneratorTests.cpp:: PASSED: CATCH_REQUIRE( multiply( j, 2 ) == j*2 ) with expansion: 204 == 204 ------------------------------------------------------------------------------- Generators over two ranges ------------------------------------------------------------------------------- GeneratorTests.cpp: ............................................................................... GeneratorTests.cpp:: PASSED: CATCH_REQUIRE( multiply( i, 2 ) == i*2 ) with expansion: 40 == 40 GeneratorTests.cpp:: PASSED: CATCH_REQUIRE( multiply( j, 2 ) == j*2 ) with expansion: 204 == 204 ------------------------------------------------------------------------------- Generators over two ranges ------------------------------------------------------------------------------- GeneratorTests.cpp: ............................................................................... GeneratorTests.cpp:: PASSED: CATCH_REQUIRE( multiply( i, 2 ) == i*2 ) with expansion: 42 == 42 GeneratorTests.cpp:: PASSED: CATCH_REQUIRE( multiply( j, 2 ) == j*2 ) with expansion: 204 == 204 ------------------------------------------------------------------------------- Generators over two ranges ------------------------------------------------------------------------------- GeneratorTests.cpp: ............................................................................... GeneratorTests.cpp:: PASSED: CATCH_REQUIRE( multiply( i, 2 ) == i*2 ) with expansion: 72 == 72 GeneratorTests.cpp:: PASSED: CATCH_REQUIRE( multiply( j, 2 ) == j*2 ) with expansion: 204 == 204 ------------------------------------------------------------------------------- Generators over two ranges ------------------------------------------------------------------------------- GeneratorTests.cpp: ............................................................................... GeneratorTests.cpp:: PASSED: CATCH_REQUIRE( multiply( i, 2 ) == i*2 ) with expansion: 2 == 2 GeneratorTests.cpp:: PASSED: CATCH_REQUIRE( multiply( j, 2 ) == j*2 ) with expansion: 206 == 206 ------------------------------------------------------------------------------- Generators over two ranges ------------------------------------------------------------------------------- GeneratorTests.cpp: ............................................................................... GeneratorTests.cpp:: PASSED: CATCH_REQUIRE( multiply( i, 2 ) == i*2 ) with expansion: 4 == 4 GeneratorTests.cpp:: PASSED: CATCH_REQUIRE( multiply( j, 2 ) == j*2 ) with expansion: 206 == 206 ------------------------------------------------------------------------------- Generators over two ranges ------------------------------------------------------------------------------- GeneratorTests.cpp: ............................................................................... GeneratorTests.cpp:: PASSED: CATCH_REQUIRE( multiply( i, 2 ) == i*2 ) with expansion: 6 == 6 GeneratorTests.cpp:: PASSED: CATCH_REQUIRE( multiply( j, 2 ) == j*2 ) with expansion: 206 == 206 ------------------------------------------------------------------------------- Generators over two ranges ------------------------------------------------------------------------------- GeneratorTests.cpp: ............................................................................... GeneratorTests.cpp:: PASSED: CATCH_REQUIRE( multiply( i, 2 ) == i*2 ) with expansion: 8 == 8 GeneratorTests.cpp:: PASSED: CATCH_REQUIRE( multiply( j, 2 ) == j*2 ) with expansion: 206 == 206 ------------------------------------------------------------------------------- Generators over two ranges ------------------------------------------------------------------------------- GeneratorTests.cpp: ............................................................................... GeneratorTests.cpp:: PASSED: CATCH_REQUIRE( multiply( i, 2 ) == i*2 ) with expansion: 10 == 10 GeneratorTests.cpp:: PASSED: CATCH_REQUIRE( multiply( j, 2 ) == j*2 ) with expansion: 206 == 206 ------------------------------------------------------------------------------- Generators over two ranges ------------------------------------------------------------------------------- GeneratorTests.cpp: ............................................................................... GeneratorTests.cpp:: PASSED: CATCH_REQUIRE( multiply( i, 2 ) == i*2 ) with expansion: 30 == 30 GeneratorTests.cpp:: PASSED: CATCH_REQUIRE( multiply( j, 2 ) == j*2 ) with expansion: 206 == 206 ------------------------------------------------------------------------------- Generators over two ranges ------------------------------------------------------------------------------- GeneratorTests.cpp: ............................................................................... GeneratorTests.cpp:: PASSED: CATCH_REQUIRE( multiply( i, 2 ) == i*2 ) with expansion: 40 == 40 GeneratorTests.cpp:: PASSED: CATCH_REQUIRE( multiply( j, 2 ) == j*2 ) with expansion: 206 == 206 ------------------------------------------------------------------------------- Generators over two ranges ------------------------------------------------------------------------------- GeneratorTests.cpp: ............................................................................... GeneratorTests.cpp:: PASSED: CATCH_REQUIRE( multiply( i, 2 ) == i*2 ) with expansion: 42 == 42 GeneratorTests.cpp:: PASSED: CATCH_REQUIRE( multiply( j, 2 ) == j*2 ) with expansion: 206 == 206 ------------------------------------------------------------------------------- Generators over two ranges ------------------------------------------------------------------------------- GeneratorTests.cpp: ............................................................................... GeneratorTests.cpp:: PASSED: CATCH_REQUIRE( multiply( i, 2 ) == i*2 ) with expansion: 72 == 72 GeneratorTests.cpp:: PASSED: CATCH_REQUIRE( multiply( j, 2 ) == j*2 ) with expansion: 206 == 206 ------------------------------------------------------------------------------- Generators over two ranges ------------------------------------------------------------------------------- GeneratorTests.cpp: ............................................................................... GeneratorTests.cpp:: PASSED: CATCH_REQUIRE( multiply( i, 2 ) == i*2 ) with expansion: 2 == 2 GeneratorTests.cpp:: PASSED: CATCH_REQUIRE( multiply( j, 2 ) == j*2 ) with expansion: 208 == 208 ------------------------------------------------------------------------------- Generators over two ranges ------------------------------------------------------------------------------- GeneratorTests.cpp: ............................................................................... GeneratorTests.cpp:: PASSED: CATCH_REQUIRE( multiply( i, 2 ) == i*2 ) with expansion: 4 == 4 GeneratorTests.cpp:: PASSED: CATCH_REQUIRE( multiply( j, 2 ) == j*2 ) with expansion: 208 == 208 ------------------------------------------------------------------------------- Generators over two ranges ------------------------------------------------------------------------------- GeneratorTests.cpp: ............................................................................... GeneratorTests.cpp:: PASSED: CATCH_REQUIRE( multiply( i, 2 ) == i*2 ) with expansion: 6 == 6 GeneratorTests.cpp:: PASSED: CATCH_REQUIRE( multiply( j, 2 ) == j*2 ) with expansion: 208 == 208 ------------------------------------------------------------------------------- Generators over two ranges ------------------------------------------------------------------------------- GeneratorTests.cpp: ............................................................................... GeneratorTests.cpp:: PASSED: CATCH_REQUIRE( multiply( i, 2 ) == i*2 ) with expansion: 8 == 8 GeneratorTests.cpp:: PASSED: CATCH_REQUIRE( multiply( j, 2 ) == j*2 ) with expansion: 208 == 208 ------------------------------------------------------------------------------- Generators over two ranges ------------------------------------------------------------------------------- GeneratorTests.cpp: ............................................................................... GeneratorTests.cpp:: PASSED: CATCH_REQUIRE( multiply( i, 2 ) == i*2 ) with expansion: 10 == 10 GeneratorTests.cpp:: PASSED: CATCH_REQUIRE( multiply( j, 2 ) == j*2 ) with expansion: 208 == 208 ------------------------------------------------------------------------------- Generators over two ranges ------------------------------------------------------------------------------- GeneratorTests.cpp: ............................................................................... GeneratorTests.cpp:: PASSED: CATCH_REQUIRE( multiply( i, 2 ) == i*2 ) with expansion: 30 == 30 GeneratorTests.cpp:: PASSED: CATCH_REQUIRE( multiply( j, 2 ) == j*2 ) with expansion: 208 == 208 ------------------------------------------------------------------------------- Generators over two ranges ------------------------------------------------------------------------------- GeneratorTests.cpp: ............................................................................... GeneratorTests.cpp:: PASSED: CATCH_REQUIRE( multiply( i, 2 ) == i*2 ) with expansion: 40 == 40 GeneratorTests.cpp:: PASSED: CATCH_REQUIRE( multiply( j, 2 ) == j*2 ) with expansion: 208 == 208 ------------------------------------------------------------------------------- Generators over two ranges ------------------------------------------------------------------------------- GeneratorTests.cpp: ............................................................................... GeneratorTests.cpp:: PASSED: CATCH_REQUIRE( multiply( i, 2 ) == i*2 ) with expansion: 42 == 42 GeneratorTests.cpp:: PASSED: CATCH_REQUIRE( multiply( j, 2 ) == j*2 ) with expansion: 208 == 208 ------------------------------------------------------------------------------- Generators over two ranges ------------------------------------------------------------------------------- GeneratorTests.cpp: ............................................................................... GeneratorTests.cpp:: PASSED: CATCH_REQUIRE( multiply( i, 2 ) == i*2 ) with expansion: 72 == 72 GeneratorTests.cpp:: PASSED: CATCH_REQUIRE( multiply( j, 2 ) == j*2 ) with expansion: 208 == 208 ------------------------------------------------------------------------------- Generators over two ranges ------------------------------------------------------------------------------- GeneratorTests.cpp: ............................................................................... GeneratorTests.cpp:: PASSED: CATCH_REQUIRE( multiply( i, 2 ) == i*2 ) with expansion: 2 == 2 GeneratorTests.cpp:: PASSED: CATCH_REQUIRE( multiply( j, 2 ) == j*2 ) with expansion: 210 == 210 ------------------------------------------------------------------------------- Generators over two ranges ------------------------------------------------------------------------------- GeneratorTests.cpp: ............................................................................... GeneratorTests.cpp:: PASSED: CATCH_REQUIRE( multiply( i, 2 ) == i*2 ) with expansion: 4 == 4 GeneratorTests.cpp:: PASSED: CATCH_REQUIRE( multiply( j, 2 ) == j*2 ) with expansion: 210 == 210 ------------------------------------------------------------------------------- Generators over two ranges ------------------------------------------------------------------------------- GeneratorTests.cpp: ............................................................................... GeneratorTests.cpp:: PASSED: CATCH_REQUIRE( multiply( i, 2 ) == i*2 ) with expansion: 6 == 6 GeneratorTests.cpp:: PASSED: CATCH_REQUIRE( multiply( j, 2 ) == j*2 ) with expansion: 210 == 210 ------------------------------------------------------------------------------- Generators over two ranges ------------------------------------------------------------------------------- GeneratorTests.cpp: ............................................................................... GeneratorTests.cpp:: PASSED: CATCH_REQUIRE( multiply( i, 2 ) == i*2 ) with expansion: 8 == 8 GeneratorTests.cpp:: PASSED: CATCH_REQUIRE( multiply( j, 2 ) == j*2 ) with expansion: 210 == 210 ------------------------------------------------------------------------------- Generators over two ranges ------------------------------------------------------------------------------- GeneratorTests.cpp: ............................................................................... GeneratorTests.cpp:: PASSED: CATCH_REQUIRE( multiply( i, 2 ) == i*2 ) with expansion: 10 == 10 GeneratorTests.cpp:: PASSED: CATCH_REQUIRE( multiply( j, 2 ) == j*2 ) with expansion: 210 == 210 ------------------------------------------------------------------------------- Generators over two ranges ------------------------------------------------------------------------------- GeneratorTests.cpp: ............................................................................... GeneratorTests.cpp:: PASSED: CATCH_REQUIRE( multiply( i, 2 ) == i*2 ) with expansion: 30 == 30 GeneratorTests.cpp:: PASSED: CATCH_REQUIRE( multiply( j, 2 ) == j*2 ) with expansion: 210 == 210 ------------------------------------------------------------------------------- Generators over two ranges ------------------------------------------------------------------------------- GeneratorTests.cpp: ............................................................................... GeneratorTests.cpp:: PASSED: CATCH_REQUIRE( multiply( i, 2 ) == i*2 ) with expansion: 40 == 40 GeneratorTests.cpp:: PASSED: CATCH_REQUIRE( multiply( j, 2 ) == j*2 ) with expansion: 210 == 210 ------------------------------------------------------------------------------- Generators over two ranges ------------------------------------------------------------------------------- GeneratorTests.cpp: ............................................................................... GeneratorTests.cpp:: PASSED: CATCH_REQUIRE( multiply( i, 2 ) == i*2 ) with expansion: 42 == 42 GeneratorTests.cpp:: PASSED: CATCH_REQUIRE( multiply( j, 2 ) == j*2 ) with expansion: 210 == 210 ------------------------------------------------------------------------------- Generators over two ranges ------------------------------------------------------------------------------- GeneratorTests.cpp: ............................................................................... GeneratorTests.cpp:: PASSED: CATCH_REQUIRE( multiply( i, 2 ) == i*2 ) with expansion: 72 == 72 GeneratorTests.cpp:: PASSED: CATCH_REQUIRE( multiply( j, 2 ) == j*2 ) with expansion: 210 == 210 ------------------------------------------------------------------------------- Generators over two ranges ------------------------------------------------------------------------------- GeneratorTests.cpp: ............................................................................... GeneratorTests.cpp:: PASSED: CATCH_REQUIRE( multiply( i, 2 ) == i*2 ) with expansion: 2 == 2 GeneratorTests.cpp:: PASSED: CATCH_REQUIRE( multiply( j, 2 ) == j*2 ) with expansion: 212 == 212 ------------------------------------------------------------------------------- Generators over two ranges ------------------------------------------------------------------------------- GeneratorTests.cpp: ............................................................................... GeneratorTests.cpp:: PASSED: CATCH_REQUIRE( multiply( i, 2 ) == i*2 ) with expansion: 4 == 4 GeneratorTests.cpp:: PASSED: CATCH_REQUIRE( multiply( j, 2 ) == j*2 ) with expansion: 212 == 212 ------------------------------------------------------------------------------- Generators over two ranges ------------------------------------------------------------------------------- GeneratorTests.cpp: ............................................................................... GeneratorTests.cpp:: PASSED: CATCH_REQUIRE( multiply( i, 2 ) == i*2 ) with expansion: 6 == 6 GeneratorTests.cpp:: PASSED: CATCH_REQUIRE( multiply( j, 2 ) == j*2 ) with expansion: 212 == 212 ------------------------------------------------------------------------------- Generators over two ranges ------------------------------------------------------------------------------- GeneratorTests.cpp: ............................................................................... GeneratorTests.cpp:: PASSED: CATCH_REQUIRE( multiply( i, 2 ) == i*2 ) with expansion: 8 == 8 GeneratorTests.cpp:: PASSED: CATCH_REQUIRE( multiply( j, 2 ) == j*2 ) with expansion: 212 == 212 ------------------------------------------------------------------------------- Generators over two ranges ------------------------------------------------------------------------------- GeneratorTests.cpp: ............................................................................... GeneratorTests.cpp:: PASSED: CATCH_REQUIRE( multiply( i, 2 ) == i*2 ) with expansion: 10 == 10 GeneratorTests.cpp:: PASSED: CATCH_REQUIRE( multiply( j, 2 ) == j*2 ) with expansion: 212 == 212 ------------------------------------------------------------------------------- Generators over two ranges ------------------------------------------------------------------------------- GeneratorTests.cpp: ............................................................................... GeneratorTests.cpp:: PASSED: CATCH_REQUIRE( multiply( i, 2 ) == i*2 ) with expansion: 30 == 30 GeneratorTests.cpp:: PASSED: CATCH_REQUIRE( multiply( j, 2 ) == j*2 ) with expansion: 212 == 212 ------------------------------------------------------------------------------- Generators over two ranges ------------------------------------------------------------------------------- GeneratorTests.cpp: ............................................................................... GeneratorTests.cpp:: PASSED: CATCH_REQUIRE( multiply( i, 2 ) == i*2 ) with expansion: 40 == 40 GeneratorTests.cpp:: PASSED: CATCH_REQUIRE( multiply( j, 2 ) == j*2 ) with expansion: 212 == 212 ------------------------------------------------------------------------------- Generators over two ranges ------------------------------------------------------------------------------- GeneratorTests.cpp: ............................................................................... GeneratorTests.cpp:: PASSED: CATCH_REQUIRE( multiply( i, 2 ) == i*2 ) with expansion: 42 == 42 GeneratorTests.cpp:: PASSED: CATCH_REQUIRE( multiply( j, 2 ) == j*2 ) with expansion: 212 == 212 ------------------------------------------------------------------------------- Generators over two ranges ------------------------------------------------------------------------------- GeneratorTests.cpp: ............................................................................... GeneratorTests.cpp:: PASSED: CATCH_REQUIRE( multiply( i, 2 ) == i*2 ) with expansion: 72 == 72 GeneratorTests.cpp:: PASSED: CATCH_REQUIRE( multiply( j, 2 ) == j*2 ) with expansion: 212 == 212 ------------------------------------------------------------------------------- Generators over two ranges ------------------------------------------------------------------------------- GeneratorTests.cpp: ............................................................................... GeneratorTests.cpp:: PASSED: CATCH_REQUIRE( multiply( i, 2 ) == i*2 ) with expansion: 2 == 2 GeneratorTests.cpp:: PASSED: CATCH_REQUIRE( multiply( j, 2 ) == j*2 ) with expansion: 214 == 214 ------------------------------------------------------------------------------- Generators over two ranges ------------------------------------------------------------------------------- GeneratorTests.cpp: ............................................................................... GeneratorTests.cpp:: PASSED: CATCH_REQUIRE( multiply( i, 2 ) == i*2 ) with expansion: 4 == 4 GeneratorTests.cpp:: PASSED: CATCH_REQUIRE( multiply( j, 2 ) == j*2 ) with expansion: 214 == 214 ------------------------------------------------------------------------------- Generators over two ranges ------------------------------------------------------------------------------- GeneratorTests.cpp: ............................................................................... GeneratorTests.cpp:: PASSED: CATCH_REQUIRE( multiply( i, 2 ) == i*2 ) with expansion: 6 == 6 GeneratorTests.cpp:: PASSED: CATCH_REQUIRE( multiply( j, 2 ) == j*2 ) with expansion: 214 == 214 ------------------------------------------------------------------------------- Generators over two ranges ------------------------------------------------------------------------------- GeneratorTests.cpp: ............................................................................... GeneratorTests.cpp:: PASSED: CATCH_REQUIRE( multiply( i, 2 ) == i*2 ) with expansion: 8 == 8 GeneratorTests.cpp:: PASSED: CATCH_REQUIRE( multiply( j, 2 ) == j*2 ) with expansion: 214 == 214 ------------------------------------------------------------------------------- Generators over two ranges ------------------------------------------------------------------------------- GeneratorTests.cpp: ............................................................................... GeneratorTests.cpp:: PASSED: CATCH_REQUIRE( multiply( i, 2 ) == i*2 ) with expansion: 10 == 10 GeneratorTests.cpp:: PASSED: CATCH_REQUIRE( multiply( j, 2 ) == j*2 ) with expansion: 214 == 214 ------------------------------------------------------------------------------- Generators over two ranges ------------------------------------------------------------------------------- GeneratorTests.cpp: ............................................................................... GeneratorTests.cpp:: PASSED: CATCH_REQUIRE( multiply( i, 2 ) == i*2 ) with expansion: 30 == 30 GeneratorTests.cpp:: PASSED: CATCH_REQUIRE( multiply( j, 2 ) == j*2 ) with expansion: 214 == 214 ------------------------------------------------------------------------------- Generators over two ranges ------------------------------------------------------------------------------- GeneratorTests.cpp: ............................................................................... GeneratorTests.cpp:: PASSED: CATCH_REQUIRE( multiply( i, 2 ) == i*2 ) with expansion: 40 == 40 GeneratorTests.cpp:: PASSED: CATCH_REQUIRE( multiply( j, 2 ) == j*2 ) with expansion: 214 == 214 ------------------------------------------------------------------------------- Generators over two ranges ------------------------------------------------------------------------------- GeneratorTests.cpp: ............................................................................... GeneratorTests.cpp:: PASSED: CATCH_REQUIRE( multiply( i, 2 ) == i*2 ) with expansion: 42 == 42 GeneratorTests.cpp:: PASSED: CATCH_REQUIRE( multiply( j, 2 ) == j*2 ) with expansion: 214 == 214 ------------------------------------------------------------------------------- Generators over two ranges ------------------------------------------------------------------------------- GeneratorTests.cpp: ............................................................................... GeneratorTests.cpp:: PASSED: CATCH_REQUIRE( multiply( i, 2 ) == i*2 ) with expansion: 72 == 72 GeneratorTests.cpp:: PASSED: CATCH_REQUIRE( multiply( j, 2 ) == j*2 ) with expansion: 214 == 214 ------------------------------------------------------------------------------- Greater-than inequalities with different epsilons ------------------------------------------------------------------------------- ApproxTests.cpp: ............................................................................... ApproxTests.cpp:: PASSED: REQUIRE( d >= Approx( 1.22 ) ) with expansion: 1.23 >= Approx( 1.22 ) ApproxTests.cpp:: PASSED: REQUIRE( d >= Approx( 1.23 ) ) with expansion: 1.23 >= Approx( 1.23 ) ApproxTests.cpp:: PASSED: REQUIRE_FALSE( d >= Approx( 1.24 ) ) with expansion: !(1.23 >= Approx( 1.24 )) ApproxTests.cpp:: PASSED: REQUIRE( d >= Approx( 1.24 ).epsilon(0.1) ) with expansion: 1.23 >= Approx( 1.24 ) ------------------------------------------------------------------------------- INFO and WARN do not abort tests ------------------------------------------------------------------------------- MessageTests.cpp: ............................................................................... MessageTests.cpp:: warning: this is a message this is a warning ------------------------------------------------------------------------------- INFO gets logged on failure ------------------------------------------------------------------------------- MessageTests.cpp: ............................................................................... MessageTests.cpp:: FAILED: REQUIRE( a == 1 ) with expansion: 2 == 1 with messages: this message should be logged so should this ------------------------------------------------------------------------------- INFO gets logged on failure, even if captured before successful assertions ------------------------------------------------------------------------------- MessageTests.cpp: ............................................................................... MessageTests.cpp:: PASSED: CHECK( a == 2 ) with expansion: 2 == 2 with message: this message may be logged later MessageTests.cpp:: FAILED: CHECK( a == 1 ) with expansion: 2 == 1 with messages: this message may be logged later this message should be logged MessageTests.cpp:: FAILED: CHECK( a == 0 ) with expansion: 2 == 0 with messages: this message may be logged later this message should be logged and this, but later MessageTests.cpp:: PASSED: CHECK( a == 2 ) with expansion: 2 == 2 with messages: this message may be logged later this message should be logged and this, but later but not this ------------------------------------------------------------------------------- Inequality checks that should fail ------------------------------------------------------------------------------- ConditionTests.cpp: ............................................................................... ConditionTests.cpp:: FAILED: CHECK( data.int_seven != 7 ) with expansion: 7 != 7 ConditionTests.cpp:: FAILED: CHECK( data.float_nine_point_one != Approx( 9.1f ) ) with expansion: 9.1f != Approx( 9.1000003815 ) ConditionTests.cpp:: FAILED: CHECK( data.double_pi != Approx( 3.1415926535 ) ) with expansion: 3.1415926535 != Approx( 3.1415926535 ) ConditionTests.cpp:: FAILED: CHECK( data.str_hello != "hello" ) with expansion: "hello" != "hello" ConditionTests.cpp:: FAILED: CHECK( data.str_hello.size() != 5 ) with expansion: 5 != 5 ------------------------------------------------------------------------------- Inequality checks that should succeed ------------------------------------------------------------------------------- ConditionTests.cpp: ............................................................................... ConditionTests.cpp:: PASSED: REQUIRE( data.int_seven != 6 ) with expansion: 7 != 6 ConditionTests.cpp:: PASSED: REQUIRE( data.int_seven != 8 ) with expansion: 7 != 8 ConditionTests.cpp:: PASSED: REQUIRE( data.float_nine_point_one != Approx( 9.11f ) ) with expansion: 9.1f != Approx( 9.1099996567 ) ConditionTests.cpp:: PASSED: REQUIRE( data.float_nine_point_one != Approx( 9.0f ) ) with expansion: 9.1f != Approx( 9.0 ) ConditionTests.cpp:: PASSED: REQUIRE( data.float_nine_point_one != Approx( 1 ) ) with expansion: 9.1f != Approx( 1.0 ) ConditionTests.cpp:: PASSED: REQUIRE( data.float_nine_point_one != Approx( 0 ) ) with expansion: 9.1f != Approx( 0.0 ) ConditionTests.cpp:: PASSED: REQUIRE( data.double_pi != Approx( 3.1415 ) ) with expansion: 3.1415926535 != Approx( 3.1415 ) ConditionTests.cpp:: PASSED: REQUIRE( data.str_hello != "goodbye" ) with expansion: "hello" != "goodbye" ConditionTests.cpp:: PASSED: REQUIRE( data.str_hello != "hell" ) with expansion: "hello" != "hell" ConditionTests.cpp:: PASSED: REQUIRE( data.str_hello != "hello1" ) with expansion: "hello" != "hello1" ConditionTests.cpp:: PASSED: REQUIRE( data.str_hello.size() != 6 ) with expansion: 5 != 6 ------------------------------------------------------------------------------- Less-than inequalities with different epsilons ------------------------------------------------------------------------------- ApproxTests.cpp: ............................................................................... ApproxTests.cpp:: PASSED: REQUIRE( d <= Approx( 1.24 ) ) with expansion: 1.23 <= Approx( 1.24 ) ApproxTests.cpp:: PASSED: REQUIRE( d <= Approx( 1.23 ) ) with expansion: 1.23 <= Approx( 1.23 ) ApproxTests.cpp:: PASSED: REQUIRE_FALSE( d <= Approx( 1.22 ) ) with expansion: !(1.23 <= Approx( 1.22 )) ApproxTests.cpp:: PASSED: REQUIRE( d <= Approx( 1.22 ).epsilon(0.1) ) with expansion: 1.23 <= Approx( 1.22 ) ------------------------------------------------------------------------------- Long strings can be wrapped plain string No wrapping ------------------------------------------------------------------------------- TestMain.cpp: ............................................................................... TestMain.cpp:: PASSED: CHECK( Text( testString, TextAttributes().setWidth( 80 ) ).toString() == testString ) with expansion: "one two three four" == "one two three four" TestMain.cpp:: PASSED: CHECK( Text( testString, TextAttributes().setWidth( 18 ) ).toString() == testString ) with expansion: "one two three four" == "one two three four" ------------------------------------------------------------------------------- Long strings can be wrapped plain string Wrapped once ------------------------------------------------------------------------------- TestMain.cpp: ............................................................................... TestMain.cpp:: PASSED: CHECK( Text( testString, TextAttributes().setWidth( 17 ) ).toString() == "one two three\nfour" ) with expansion: "one two three four" == "one two three four" TestMain.cpp:: PASSED: CHECK( Text( testString, TextAttributes().setWidth( 16 ) ).toString() == "one two three\nfour" ) with expansion: "one two three four" == "one two three four" TestMain.cpp:: PASSED: CHECK( Text( testString, TextAttributes().setWidth( 14 ) ).toString() == "one two three\nfour" ) with expansion: "one two three four" == "one two three four" TestMain.cpp:: PASSED: CHECK( Text( testString, TextAttributes().setWidth( 13 ) ).toString() == "one two three\nfour" ) with expansion: "one two three four" == "one two three four" TestMain.cpp:: PASSED: CHECK( Text( testString, TextAttributes().setWidth( 12 ) ).toString() == "one two\nthree four" ) with expansion: "one two three four" == "one two three four" ------------------------------------------------------------------------------- Long strings can be wrapped plain string Wrapped twice ------------------------------------------------------------------------------- TestMain.cpp: ............................................................................... TestMain.cpp:: PASSED: CHECK( Text( testString, TextAttributes().setWidth( 9 ) ).toString() == "one two\nthree\nfour" ) with expansion: "one two three four" == "one two three four" TestMain.cpp:: PASSED: CHECK( Text( testString, TextAttributes().setWidth( 8 ) ).toString() == "one two\nthree\nfour" ) with expansion: "one two three four" == "one two three four" TestMain.cpp:: PASSED: CHECK( Text( testString, TextAttributes().setWidth( 7 ) ).toString() == "one two\nthree\nfour" ) with expansion: "one two three four" == "one two three four" ------------------------------------------------------------------------------- Long strings can be wrapped plain string Wrapped three times ------------------------------------------------------------------------------- TestMain.cpp: ............................................................................... TestMain.cpp:: PASSED: CHECK( Text( testString, TextAttributes().setWidth( 6 ) ).toString() == "one\ntwo\nthree\nfour" ) with expansion: "one two three four" == "one two three four" TestMain.cpp:: PASSED: CHECK( Text( testString, TextAttributes().setWidth( 5 ) ).toString() == "one\ntwo\nthree\nfour" ) with expansion: "one two three four" == "one two three four" ------------------------------------------------------------------------------- Long strings can be wrapped plain string Short wrap ------------------------------------------------------------------------------- TestMain.cpp: ............................................................................... TestMain.cpp:: PASSED: CHECK( Text( "abcdef", TextAttributes().setWidth( 4 ) ).toString() == "abc-\ndef" ) with expansion: "abc- def" == "abc- def" TestMain.cpp:: PASSED: CHECK( Text( "abcdefg", TextAttributes().setWidth( 4 ) ).toString() == "abc-\ndefg" ) with expansion: "abc- defg" == "abc- defg" TestMain.cpp:: PASSED: CHECK( Text( "abcdefgh", TextAttributes().setWidth( 4 ) ).toString() == "abc-\ndef-\ngh" ) with expansion: "abc- def- gh" == "abc- def- gh" TestMain.cpp:: PASSED: CHECK( Text( testString, TextAttributes().setWidth( 4 ) ).toString() == "one\ntwo\nthr-\nee\nfour" ) with expansion: "one two thr- ee four" == "one two thr- ee four" TestMain.cpp:: PASSED: CHECK( Text( testString, TextAttributes().setWidth( 3 ) ).toString() == "one\ntwo\nth-\nree\nfo-\nur" ) with expansion: "one two th- ree fo- ur" == "one two th- ree fo- ur" ------------------------------------------------------------------------------- Long strings can be wrapped plain string As container ------------------------------------------------------------------------------- TestMain.cpp: ............................................................................... TestMain.cpp:: PASSED: REQUIRE( text.size() == 4 ) with expansion: 4 == 4 TestMain.cpp:: PASSED: CHECK( text[0] == "one" ) with expansion: "one" == "one" TestMain.cpp:: PASSED: CHECK( text[1] == "two" ) with expansion: "two" == "two" TestMain.cpp:: PASSED: CHECK( text[2] == "three" ) with expansion: "three" == "three" TestMain.cpp:: PASSED: CHECK( text[3] == "four" ) with expansion: "four" == "four" ------------------------------------------------------------------------------- Long strings can be wrapped plain string Indent first line differently ------------------------------------------------------------------------------- TestMain.cpp: ............................................................................... TestMain.cpp:: PASSED: CHECK( text.toString() == " one two\n three\n four" ) with expansion: " one two three four" == " one two three four" ------------------------------------------------------------------------------- Long strings can be wrapped With newlines No wrapping ------------------------------------------------------------------------------- TestMain.cpp: ............................................................................... TestMain.cpp:: PASSED: CHECK( Text( testString, TextAttributes().setWidth( 80 ) ).toString() == testString ) with expansion: "one two three four" == "one two three four" TestMain.cpp:: PASSED: CHECK( Text( testString, TextAttributes().setWidth( 18 ) ).toString() == testString ) with expansion: "one two three four" == "one two three four" TestMain.cpp:: PASSED: CHECK( Text( testString, TextAttributes().setWidth( 10 ) ).toString() == testString ) with expansion: "one two three four" == "one two three four" ------------------------------------------------------------------------------- Long strings can be wrapped With newlines Trailing newline ------------------------------------------------------------------------------- TestMain.cpp: ............................................................................... TestMain.cpp:: PASSED: CHECK( Text( "abcdef\n", TextAttributes().setWidth( 10 ) ).toString() == "abcdef" ) with expansion: "abcdef" == "abcdef" TestMain.cpp:: PASSED: CHECK( Text( "abcdef", TextAttributes().setWidth( 6 ) ).toString() == "abcdef" ) with expansion: "abcdef" == "abcdef" TestMain.cpp:: PASSED: CHECK( Text( "abcdef\n", TextAttributes().setWidth( 6 ) ).toString() == "abcdef" ) with expansion: "abcdef" == "abcdef" TestMain.cpp:: PASSED: CHECK( Text( "abcdef\n", TextAttributes().setWidth( 5 ) ).toString() == "abcd-\nef" ) with expansion: "abcd- ef" == "abcd- ef" ------------------------------------------------------------------------------- Long strings can be wrapped With newlines Wrapped once ------------------------------------------------------------------------------- TestMain.cpp: ............................................................................... TestMain.cpp:: PASSED: CHECK( Text( testString, TextAttributes().setWidth( 9 ) ).toString() == "one two\nthree\nfour" ) with expansion: "one two three four" == "one two three four" TestMain.cpp:: PASSED: CHECK( Text( testString, TextAttributes().setWidth( 8 ) ).toString() == "one two\nthree\nfour" ) with expansion: "one two three four" == "one two three four" TestMain.cpp:: PASSED: CHECK( Text( testString, TextAttributes().setWidth( 7 ) ).toString() == "one two\nthree\nfour" ) with expansion: "one two three four" == "one two three four" ------------------------------------------------------------------------------- Long strings can be wrapped With newlines Wrapped twice ------------------------------------------------------------------------------- TestMain.cpp: ............................................................................... TestMain.cpp:: PASSED: CHECK( Text( testString, TextAttributes().setWidth( 6 ) ).toString() == "one\ntwo\nthree\nfour" ) with expansion: "one two three four" == "one two three four" ------------------------------------------------------------------------------- Long strings can be wrapped With wrap-before/ after characters No wrapping ------------------------------------------------------------------------------- TestMain.cpp: ............................................................................... TestMain.cpp:: PASSED: CHECK( Text( testString, TextAttributes().setWidth( 80 ) ).toString() == testString ) with expansion: "one,two(three) " == "one,two(three) " TestMain.cpp:: PASSED: CHECK( Text( testString, TextAttributes().setWidth( 24 ) ).toString() == testString ) with expansion: "one,two(three) " == "one,two(three) " ------------------------------------------------------------------------------- Long strings can be wrapped With wrap-before/ after characters Wrap before ------------------------------------------------------------------------------- TestMain.cpp: ............................................................................... TestMain.cpp:: PASSED: CHECK( Text( testString, TextAttributes().setWidth( 11 ) ).toString() == "one,two\n(three)\n" ) with expansion: "one,two (three) " == "one,two (three) " ------------------------------------------------------------------------------- Long strings can be wrapped With wrap-before/ after characters Wrap after ------------------------------------------------------------------------------- TestMain.cpp: ............................................................................... TestMain.cpp:: PASSED: CHECK( Text( testString, TextAttributes().setWidth( 6 ) ).toString() == "one,\ntwo\n(thre-\ne)\n" ) with expansion: "one, two (thre- e) " == "one, two (thre- e) " TestMain.cpp:: PASSED: CHECK( Text( testString, TextAttributes().setWidth( 5 ) ).toString() == "one,\ntwo\n(thr-\nee)\n" ) with expansion: "one, two (thr- ee) " == "one, two (thr- ee) " TestMain.cpp:: PASSED: CHECK( Text( testString, TextAttributes().setWidth( 4 ) ).toString() == "one,\ntwo\n(th-\nree)\n" ) with expansion: "one, two (th- ree) " == "one, two (th- ree) " ------------------------------------------------------------------------------- Long text is truncated ------------------------------------------------------------------------------- TestMain.cpp: ............................................................................... TestMain.cpp:: PASSED: CHECK_THAT( t.toString(), EndsWith( "... message truncated due to excessive size" ) ) with expansion: "***************************************************************************- ***- ****************************************************************************- **- ************************ ****************************************************************************- **- ****************************************************************************- **- ************************ ****************************************************************************- **- ****************************************************************************- **- ************************ ****************************************************************************- **- ****************************************************************************- **- ************************ ****************************************************************************- **- ****************************************************************************- **- ************************ ****************************************************************************- **- ****************************************************************************- **- ************************ ****************************************************************************- **- ****************************************************************************- **- ************************ ****************************************************************************- **- ****************************************************************************- **- ************************ ****************************************************************************- **- ****************************************************************************- **- ************************ ****************************************************************************- **- ****************************************************************************- **- ************************ ****************************************************************************- **- ****************************************************************************- **- ************************ ****************************************************************************- **- ****************************************************************************- **- ************************ ****************************************************************************- **- ****************************************************************************- **- ************************ ****************************************************************************- **- ****************************************************************************- **- ************************ ****************************************************************************- **- ****************************************************************************- **- ************************ ****************************************************************************- **- ****************************************************************************- **- ************************ ****************************************************************************- **- ****************************************************************************- **- ************************ ****************************************************************************- **- ****************************************************************************- **- ************************ ****************************************************************************- **- ****************************************************************************- **- ************************ ****************************************************************************- **- ****************************************************************************- **- ************************ ****************************************************************************- **- ****************************************************************************- **- ************************ ****************************************************************************- **- ****************************************************************************- **- ************************ ****************************************************************************- **- ****************************************************************************- **- ************************ ****************************************************************************- **- ****************************************************************************- **- ************************ ****************************************************************************- **- ****************************************************************************- **- ************************ ****************************************************************************- **- ****************************************************************************- **- ************************ ****************************************************************************- **- ****************************************************************************- **- ************************ ****************************************************************************- **- ****************************************************************************- **- ************************ ****************************************************************************- **- ****************************************************************************- **- ************************ ****************************************************************************- **- ****************************************************************************- **- ************************ ****************************************************************************- **- ****************************************************************************- **- ************************ ****************************************************************************- **- ****************************************************************************- **- ************************ ****************************************************************************- **- ****************************************************************************- **- ************************ ****************************************************************************- **- ****************************************************************************- **- ************************ ****************************************************************************- **- ****************************************************************************- **- ************************ ****************************************************************************- **- ****************************************************************************- **- ************************ ****************************************************************************- **- ****************************************************************************- **- ************************ ****************************************************************************- **- ****************************************************************************- **- ************************ ****************************************************************************- **- ****************************************************************************- **- ************************ ****************************************************************************- **- ****************************************************************************- **- ************************ ****************************************************************************- **- ****************************************************************************- **- ************************ ****************************************************************************- **- ****************************************************************************- **- ************************ ****************************************************************************- **- ****************************************************************************- **- ************************ ****************************************************************************- **- ****************************************************************************- **- ************************ ****************************************************************************- **- ****************************************************************************- **- ************************ ****************************************************************************- **- ****************************************************************************- **- ************************ ****************************************************************************- **- ****************************************************************************- **- ************************ ****************************************************************************- **- ****************************************************************************- **- ************************ ****************************************************************************- **- ****************************************************************************- **- ************************ ****************************************************************************- **- ****************************************************************************- **- ************************ ****************************************************************************- **- ****************************************************************************- **- ************************ ****************************************************************************- **- ****************************************************************************- **- ************************ ****************************************************************************- **- ****************************************************************************- **- ************************ ****************************************************************************- **- ****************************************************************************- **- ************************ ****************************************************************************- **- ****************************************************************************- **- ************************ ****************************************************************************- **- ****************************************************************************- **- ************************ ****************************************************************************- **- ****************************************************************************- **- ************************ ****************************************************************************- **- ****************************************************************************- **- ************************ ****************************************************************************- **- ****************************************************************************- **- ************************ ****************************************************************************- **- ****************************************************************************- **- ************************ ****************************************************************************- **- ****************************************************************************- **- ************************ ****************************************************************************- **- ****************************************************************************- **- ************************ ****************************************************************************- **- ****************************************************************************- **- ************************ ****************************************************************************- **- ****************************************************************************- **- ************************ ****************************************************************************- **- ****************************************************************************- **- ************************ ****************************************************************************- **- ****************************************************************************- **- ************************ ****************************************************************************- **- ****************************************************************************- **- ************************ ****************************************************************************- **- ****************************************************************************- **- ************************ ****************************************************************************- **- ****************************************************************************- **- ************************ ****************************************************************************- **- ****************************************************************************- **- ************************ ****************************************************************************- **- ****************************************************************************- **- ************************ ****************************************************************************- **- ****************************************************************************- **- ************************ ****************************************************************************- **- ****************************************************************************- **- ************************ ****************************************************************************- **- ****************************************************************************- **- ************************ ****************************************************************************- **- ****************************************************************************- **- ************************ ****************************************************************************- **- ****************************************************************************- **- ************************ ****************************************************************************- **- ****************************************************************************- **- ************************ ****************************************************************************- **- ****************************************************************************- **- ************************ ****************************************************************************- **- ****************************************************************************- **- ************************ ****************************************************************************- **- ****************************************************************************- **- ************************ ****************************************************************************- **- ****************************************************************************- **- ************************ ****************************************************************************- **- ****************************************************************************- **- ************************ ****************************************************************************- **- ****************************************************************************- **- ************************ ****************************************************************************- **- ****************************************************************************- **- ************************ ****************************************************************************- **- ****************************************************************************- **- ************************ ****************************************************************************- **- ****************************************************************************- **- ************************ ****************************************************************************- **- ****************************************************************************- **- ************************ ****************************************************************************- **- ****************************************************************************- **- ************************ ****************************************************************************- **- ****************************************************************************- **- ************************ ****************************************************************************- **- ****************************************************************************- **- ************************ ****************************************************************************- **- ****************************************************************************- **- ************************ ****************************************************************************- **- ****************************************************************************- **- ************************ ****************************************************************************- **- ****************************************************************************- **- ************************ ****************************************************************************- **- ****************************************************************************- **- ************************ ****************************************************************************- **- ****************************************************************************- **- ************************ ****************************************************************************- **- ****************************************************************************- **- ************************ ****************************************************************************- **- ****************************************************************************- **- ************************ ****************************************************************************- **- ****************************************************************************- **- ************************ ****************************************************************************- **- ****************************************************************************- **- ************************ ****************************************************************************- **- ****************************************************************************- **- ************************ ****************************************************************************- **- ****************************************************************************- **- ************************ ****************************************************************************- **- ****************************************************************************- **- ************************ ****************************************************************************- **- ****************************************************************************- **- ************************ ****************************************************************************- **- ****************************************************************************- **- ************************ ****************************************************************************- **- ****************************************************************************- **- ************************ ****************************************************************************- **- ****************************************************************************- **- ************************ ****************************************************************************- **- ****************************************************************************- **- ************************ ****************************************************************************- **- ****************************************************************************- **- ************************ ****************************************************************************- **- ****************************************************************************- **- ************************ ****************************************************************************- **- ****************************************************************************- **- ************************ ****************************************************************************- **- ****************************************************************************- **- ************************ ****************************************************************************- **- ****************************************************************************- **- ************************ ****************************************************************************- **- ****************************************************************************- **- ************************ ****************************************************************************- **- ****************************************************************************- **- ************************ ****************************************************************************- **- ****************************************************************************- **- ************************ ****************************************************************************- **- ****************************************************************************- **- ************************ ****************************************************************************- **- ****************************************************************************- **- ************************ ****************************************************************************- **- ****************************************************************************- **- ************************ ****************************************************************************- **- ****************************************************************************- **- ************************ ****************************************************************************- **- ****************************************************************************- **- ************************ ****************************************************************************- **- ****************************************************************************- **- ************************ ****************************************************************************- **- ****************************************************************************- **- ************************ ****************************************************************************- **- ****************************************************************************- **- ************************ ****************************************************************************- **- ****************************************************************************- **- ************************ ****************************************************************************- **- ****************************************************************************- **- ************************ ****************************************************************************- **- ****************************************************************************- **- ************************ ****************************************************************************- **- ****************************************************************************- **- ************************ ****************************************************************************- **- ****************************************************************************- **- ************************ ****************************************************************************- **- ****************************************************************************- **- ************************ ****************************************************************************- **- ****************************************************************************- **- ************************ ****************************************************************************- **- ****************************************************************************- **- ************************ ****************************************************************************- **- ****************************************************************************- **- ************************ ****************************************************************************- **- ****************************************************************************- **- ************************ ****************************************************************************- **- ****************************************************************************- **- ************************ ****************************************************************************- **- ****************************************************************************- **- ************************ ****************************************************************************- **- ****************************************************************************- **- ************************ ****************************************************************************- **- ****************************************************************************- **- ************************ ****************************************************************************- **- ****************************************************************************- **- ************************ ****************************************************************************- **- ****************************************************************************- **- ************************ ****************************************************************************- **- ****************************************************************************- **- ************************ ****************************************************************************- **- ****************************************************************************- **- ************************ ****************************************************************************- **- ****************************************************************************- **- ************************ ****************************************************************************- **- ****************************************************************************- **- ************************ ****************************************************************************- **- ****************************************************************************- **- ************************ ****************************************************************************- **- ****************************************************************************- **- ************************ ****************************************************************************- **- ****************************************************************************- **- ************************ ****************************************************************************- **- ****************************************************************************- **- ************************ ****************************************************************************- **- ****************************************************************************- **- ************************ ****************************************************************************- **- ****************************************************************************- **- ************************ ****************************************************************************- **- ****************************************************************************- **- ************************ ****************************************************************************- **- ****************************************************************************- **- ************************ ****************************************************************************- **- ****************************************************************************- **- ************************ ****************************************************************************- **- ****************************************************************************- **- ************************ ****************************************************************************- **- ****************************************************************************- **- ************************ ****************************************************************************- **- ****************************************************************************- **- ************************ ****************************************************************************- **- ****************************************************************************- **- ************************ ****************************************************************************- **- ****************************************************************************- **- ************************ ****************************************************************************- **- ****************************************************************************- **- ************************ ****************************************************************************- **- ****************************************************************************- **- ************************ ****************************************************************************- **- ****************************************************************************- **- ************************ ****************************************************************************- **- ****************************************************************************- **- ************************ ****************************************************************************- **- ****************************************************************************- **- ************************ ****************************************************************************- **- ****************************************************************************- **- ************************ ****************************************************************************- **- ****************************************************************************- **- ************************ ****************************************************************************- **- ****************************************************************************- **- ************************ ****************************************************************************- **- ****************************************************************************- **- ************************ ****************************************************************************- **- ****************************************************************************- **- ************************ ****************************************************************************- **- ****************************************************************************- **- ************************ ****************************************************************************- **- ****************************************************************************- **- ************************ ****************************************************************************- **- ****************************************************************************- **- ************************ ****************************************************************************- **- ****************************************************************************- **- ************************ ****************************************************************************- **- ****************************************************************************- **- ************************ ****************************************************************************- **- ****************************************************************************- **- ************************ ****************************************************************************- **- ****************************************************************************- **- ************************ ****************************************************************************- **- ****************************************************************************- **- ************************ ****************************************************************************- **- ****************************************************************************- **- ************************ ****************************************************************************- **- ****************************************************************************- **- ************************ ****************************************************************************- **- ****************************************************************************- **- ************************ ****************************************************************************- **- ****************************************************************************- **- ************************ ****************************************************************************- **- ****************************************************************************- **- ************************ ****************************************************************************- **- ****************************************************************************- **- ************************ ****************************************************************************- **- ****************************************************************************- **- ************************ ****************************************************************************- **- ****************************************************************************- **- ************************ ****************************************************************************- **- ****************************************************************************- **- ************************ ****************************************************************************- **- ****************************************************************************- **- ************************ ****************************************************************************- **- ****************************************************************************- **- ************************ ****************************************************************************- **- ****************************************************************************- **- ************************ ****************************************************************************- **- ****************************************************************************- **- ************************ ****************************************************************************- **- ****************************************************************************- **- ************************ ****************************************************************************- **- ****************************************************************************- **- ************************ ****************************************************************************- **- ****************************************************************************- **- ************************ ****************************************************************************- **- ****************************************************************************- **- ************************ ****************************************************************************- **- ****************************************************************************- **- ************************ ****************************************************************************- **- ****************************************************************************- **- ************************ ****************************************************************************- **- ****************************************************************************- **- ************************ ****************************************************************************- **- ****************************************************************************- **- ************************ ****************************************************************************- **- ****************************************************************************- **- ************************ ****************************************************************************- **- ****************************************************************************- **- ************************ ****************************************************************************- **- ****************************************************************************- **- ************************ ****************************************************************************- **- ****************************************************************************- **- ************************ ... message truncated due to excessive size ------------------------------------------------------------------------------- ManuallyRegistered ------------------------------------------------------------------------------- TestMain.cpp: ............................................................................... TestMain.cpp:: PASSED: with message: was called ------------------------------------------------------------------------------- Matchers can be (AllOf) composed with the && operator ------------------------------------------------------------------------------- MatchersTests.cpp: ............................................................................... MatchersTests.cpp:: PASSED: CHECK_THAT( testStringForMatching(), Contains( "string" ) && Contains( "abc" ) && Contains( "substring" ) && Contains( "contains" ) ) with expansion: "this string contains 'abc' as a substring" ( contains: "string" and contains: "abc" and contains: "substring" and contains: "contains" ) ------------------------------------------------------------------------------- Matchers can be (AnyOf) composed with the || operator ------------------------------------------------------------------------------- MatchersTests.cpp: ............................................................................... MatchersTests.cpp:: PASSED: CHECK_THAT( testStringForMatching(), Contains( "string" ) || Contains( "different" ) || Contains( "random" ) ) with expansion: "this string contains 'abc' as a substring" ( contains: "string" or contains: "different" or contains: "random" ) MatchersTests.cpp:: PASSED: CHECK_THAT( testStringForMatching2(), Contains( "string" ) || Contains( "different" ) || Contains( "random" ) ) with expansion: "some completely different text that contains one common word" ( contains: "string" or contains: "different" or contains: "random" ) ------------------------------------------------------------------------------- Matchers can be composed with both && and || ------------------------------------------------------------------------------- MatchersTests.cpp: ............................................................................... MatchersTests.cpp:: PASSED: CHECK_THAT( testStringForMatching(), ( Contains( "string" ) || Contains( "different" ) ) && Contains( "substring" ) ) with expansion: "this string contains 'abc' as a substring" ( ( contains: "string" or contains: "different" ) and contains: "substring" ) ------------------------------------------------------------------------------- Matchers can be composed with both && and || - failing ------------------------------------------------------------------------------- MatchersTests.cpp: ............................................................................... MatchersTests.cpp:: FAILED: CHECK_THAT( testStringForMatching(), ( Contains( "string" ) || Contains( "different" ) ) && Contains( "random" ) ) with expansion: "this string contains 'abc' as a substring" ( ( contains: "string" or contains: "different" ) and contains: "random" ) ------------------------------------------------------------------------------- Matchers can be negated (Not) with the ! operator ------------------------------------------------------------------------------- MatchersTests.cpp: ............................................................................... MatchersTests.cpp:: PASSED: CHECK_THAT( testStringForMatching(), !Contains( "different" ) ) with expansion: "this string contains 'abc' as a substring" not contains: "different" ------------------------------------------------------------------------------- Matchers can be negated (Not) with the ! operator - failing ------------------------------------------------------------------------------- MatchersTests.cpp: ............................................................................... MatchersTests.cpp:: FAILED: CHECK_THAT( testStringForMatching(), !Contains( "substring" ) ) with expansion: "this string contains 'abc' as a substring" not contains: "substring" ------------------------------------------------------------------------------- Mismatching exception messages failing the test ------------------------------------------------------------------------------- ExceptionTests.cpp: ............................................................................... ExceptionTests.cpp:: PASSED: REQUIRE_THROWS_WITH( thisThrows(), "expected exception" ) ExceptionTests.cpp:: FAILED: REQUIRE_THROWS_WITH( thisThrows(), "should fail" ) with expansion: expected exception ------------------------------------------------------------------------------- Nice descriptive name ------------------------------------------------------------------------------- MiscTests.cpp: ............................................................................... MiscTests.cpp:: warning: This one ran ------------------------------------------------------------------------------- Non-std exceptions can be translated ------------------------------------------------------------------------------- ExceptionTests.cpp: ............................................................................... ExceptionTests.cpp:: FAILED: due to unexpected exception with message: custom exception ------------------------------------------------------------------------------- NotImplemented exception ------------------------------------------------------------------------------- ExceptionTests.cpp: ............................................................................... ExceptionTests.cpp:: PASSED: REQUIRE_THROWS( thisFunctionNotImplemented( 7 ) ) ------------------------------------------------------------------------------- Objects that evaluated in boolean contexts can be checked ------------------------------------------------------------------------------- TrickyTests.cpp: ............................................................................... TrickyTests.cpp:: PASSED: CHECK( True ) with expansion: 1 TrickyTests.cpp:: PASSED: CHECK( !False ) with expansion: true TrickyTests.cpp:: PASSED: CHECK_FALSE( False ) with expansion: !0 ------------------------------------------------------------------------------- Operators at different namespace levels not hijacked by Koenig lookup ------------------------------------------------------------------------------- TrickyTests.cpp: ............................................................................... TrickyTests.cpp:: PASSED: REQUIRE( 0x == o ) with expansion: 3221225472 (0x) == {?} ------------------------------------------------------------------------------- Ordering comparison checks that should fail ------------------------------------------------------------------------------- ConditionTests.cpp: ............................................................................... ConditionTests.cpp:: FAILED: CHECK( data.int_seven > 7 ) with expansion: 7 > 7 ConditionTests.cpp:: FAILED: CHECK( data.int_seven < 7 ) with expansion: 7 < 7 ConditionTests.cpp:: FAILED: CHECK( data.int_seven > 8 ) with expansion: 7 > 8 ConditionTests.cpp:: FAILED: CHECK( data.int_seven < 6 ) with expansion: 7 < 6 ConditionTests.cpp:: FAILED: CHECK( data.int_seven < 0 ) with expansion: 7 < 0 ConditionTests.cpp:: FAILED: CHECK( data.int_seven < -1 ) with expansion: 7 < -1 ConditionTests.cpp:: FAILED: CHECK( data.int_seven >= 8 ) with expansion: 7 >= 8 ConditionTests.cpp:: FAILED: CHECK( data.int_seven <= 6 ) with expansion: 7 <= 6 ConditionTests.cpp:: FAILED: CHECK( data.float_nine_point_one < 9 ) with expansion: 9.1f < 9 ConditionTests.cpp:: FAILED: CHECK( data.float_nine_point_one > 10 ) with expansion: 9.1f > 10 ConditionTests.cpp:: FAILED: CHECK( data.float_nine_point_one > 9.2 ) with expansion: 9.1f > 9.2 ConditionTests.cpp:: FAILED: CHECK( data.str_hello > "hello" ) with expansion: "hello" > "hello" ConditionTests.cpp:: FAILED: CHECK( data.str_hello < "hello" ) with expansion: "hello" < "hello" ConditionTests.cpp:: FAILED: CHECK( data.str_hello > "hellp" ) with expansion: "hello" > "hellp" ConditionTests.cpp:: FAILED: CHECK( data.str_hello > "z" ) with expansion: "hello" > "z" ConditionTests.cpp:: FAILED: CHECK( data.str_hello < "hellm" ) with expansion: "hello" < "hellm" ConditionTests.cpp:: FAILED: CHECK( data.str_hello < "a" ) with expansion: "hello" < "a" ConditionTests.cpp:: FAILED: CHECK( data.str_hello >= "z" ) with expansion: "hello" >= "z" ConditionTests.cpp:: FAILED: CHECK( data.str_hello <= "a" ) with expansion: "hello" <= "a" ------------------------------------------------------------------------------- Ordering comparison checks that should succeed ------------------------------------------------------------------------------- ConditionTests.cpp: ............................................................................... ConditionTests.cpp:: PASSED: REQUIRE( data.int_seven < 8 ) with expansion: 7 < 8 ConditionTests.cpp:: PASSED: REQUIRE( data.int_seven > 6 ) with expansion: 7 > 6 ConditionTests.cpp:: PASSED: REQUIRE( data.int_seven > 0 ) with expansion: 7 > 0 ConditionTests.cpp:: PASSED: REQUIRE( data.int_seven > -1 ) with expansion: 7 > -1 ConditionTests.cpp:: PASSED: REQUIRE( data.int_seven >= 7 ) with expansion: 7 >= 7 ConditionTests.cpp:: PASSED: REQUIRE( data.int_seven >= 6 ) with expansion: 7 >= 6 ConditionTests.cpp:: PASSED: REQUIRE( data.int_seven <= 7 ) with expansion: 7 <= 7 ConditionTests.cpp:: PASSED: REQUIRE( data.int_seven <= 8 ) with expansion: 7 <= 8 ConditionTests.cpp:: PASSED: REQUIRE( data.float_nine_point_one > 9 ) with expansion: 9.1f > 9 ConditionTests.cpp:: PASSED: REQUIRE( data.float_nine_point_one < 10 ) with expansion: 9.1f < 10 ConditionTests.cpp:: PASSED: REQUIRE( data.float_nine_point_one < 9.2 ) with expansion: 9.1f < 9.2 ConditionTests.cpp:: PASSED: REQUIRE( data.str_hello <= "hello" ) with expansion: "hello" <= "hello" ConditionTests.cpp:: PASSED: REQUIRE( data.str_hello >= "hello" ) with expansion: "hello" >= "hello" ConditionTests.cpp:: PASSED: REQUIRE( data.str_hello < "hellp" ) with expansion: "hello" < "hellp" ConditionTests.cpp:: PASSED: REQUIRE( data.str_hello < "zebra" ) with expansion: "hello" < "zebra" ConditionTests.cpp:: PASSED: REQUIRE( data.str_hello > "hellm" ) with expansion: "hello" > "hellm" ConditionTests.cpp:: PASSED: REQUIRE( data.str_hello > "a" ) with expansion: "hello" > "a" ------------------------------------------------------------------------------- Output from all sections is reported one ------------------------------------------------------------------------------- MessageTests.cpp: ............................................................................... MessageTests.cpp:: FAILED: explicitly with message: Message from section one ------------------------------------------------------------------------------- Output from all sections is reported two ------------------------------------------------------------------------------- MessageTests.cpp: ............................................................................... MessageTests.cpp:: FAILED: explicitly with message: Message from section two ------------------------------------------------------------------------------- Parse test names and tags Empty test spec should have no filters ------------------------------------------------------------------------------- CmdLineTests.cpp: ............................................................................... CmdLineTests.cpp:: PASSED: CHECK( spec.hasFilters() == false ) with expansion: false == false CmdLineTests.cpp:: PASSED: CHECK( spec.matches( tcA ) == false ) with expansion: false == false CmdLineTests.cpp:: PASSED: CHECK( spec.matches( tcB ) == false ) with expansion: false == false ------------------------------------------------------------------------------- Parse test names and tags Test spec from empty string should have no filters ------------------------------------------------------------------------------- CmdLineTests.cpp: ............................................................................... CmdLineTests.cpp:: PASSED: CHECK( spec.hasFilters() == false ) with expansion: false == false CmdLineTests.cpp:: PASSED: CHECK( spec.matches(tcA ) == false ) with expansion: false == false CmdLineTests.cpp:: PASSED: CHECK( spec.matches( tcB ) == false ) with expansion: false == false ------------------------------------------------------------------------------- Parse test names and tags Test spec from just a comma should have no filters ------------------------------------------------------------------------------- CmdLineTests.cpp: ............................................................................... CmdLineTests.cpp:: PASSED: CHECK( spec.hasFilters() == false ) with expansion: false == false CmdLineTests.cpp:: PASSED: CHECK( spec.matches( tcA ) == false ) with expansion: false == false CmdLineTests.cpp:: PASSED: CHECK( spec.matches( tcB ) == false ) with expansion: false == false ------------------------------------------------------------------------------- Parse test names and tags Test spec from name should have one filter ------------------------------------------------------------------------------- CmdLineTests.cpp: ............................................................................... CmdLineTests.cpp:: PASSED: CHECK( spec.hasFilters() == true ) with expansion: true == true CmdLineTests.cpp:: PASSED: CHECK( spec.matches( tcA ) == false ) with expansion: false == false CmdLineTests.cpp:: PASSED: CHECK( spec.matches( tcB ) == true ) with expansion: true == true ------------------------------------------------------------------------------- Parse test names and tags Test spec from quoted name should have one filter ------------------------------------------------------------------------------- CmdLineTests.cpp: ............................................................................... CmdLineTests.cpp:: PASSED: CHECK( spec.hasFilters() == true ) with expansion: true == true CmdLineTests.cpp:: PASSED: CHECK( spec.matches( tcA ) == false ) with expansion: false == false CmdLineTests.cpp:: PASSED: CHECK( spec.matches( tcB ) == true ) with expansion: true == true ------------------------------------------------------------------------------- Parse test names and tags Test spec from name should have one filter ------------------------------------------------------------------------------- CmdLineTests.cpp: ............................................................................... CmdLineTests.cpp:: PASSED: CHECK( spec.hasFilters() == true ) with expansion: true == true CmdLineTests.cpp:: PASSED: CHECK( spec.matches( tcA ) == false ) with expansion: false == false CmdLineTests.cpp:: PASSED: CHECK( spec.matches( tcB ) == true ) with expansion: true == true CmdLineTests.cpp:: PASSED: CHECK( spec.matches( tcC ) == false ) with expansion: false == false ------------------------------------------------------------------------------- Parse test names and tags Wildcard at the start ------------------------------------------------------------------------------- CmdLineTests.cpp: ............................................................................... CmdLineTests.cpp:: PASSED: CHECK( spec.hasFilters() == true ) with expansion: true == true CmdLineTests.cpp:: PASSED: CHECK( spec.matches( tcA ) == false ) with expansion: false == false CmdLineTests.cpp:: PASSED: CHECK( spec.matches( tcB ) == false ) with expansion: false == false CmdLineTests.cpp:: PASSED: CHECK( spec.matches( tcC ) == true ) with expansion: true == true CmdLineTests.cpp:: PASSED: CHECK( spec.matches( tcD ) == false ) with expansion: false == false CmdLineTests.cpp:: PASSED: CHECK( parseTestSpec( "*a" ).matches( tcA ) == true ) with expansion: true == true ------------------------------------------------------------------------------- Parse test names and tags Wildcard at the end ------------------------------------------------------------------------------- CmdLineTests.cpp: ............................................................................... CmdLineTests.cpp:: PASSED: CHECK( spec.hasFilters() == true ) with expansion: true == true CmdLineTests.cpp:: PASSED: CHECK( spec.matches( tcA ) == false ) with expansion: false == false CmdLineTests.cpp:: PASSED: CHECK( spec.matches( tcB ) == false ) with expansion: false == false CmdLineTests.cpp:: PASSED: CHECK( spec.matches( tcC ) == true ) with expansion: true == true CmdLineTests.cpp:: PASSED: CHECK( spec.matches( tcD ) == false ) with expansion: false == false CmdLineTests.cpp:: PASSED: CHECK( parseTestSpec( "a*" ).matches( tcA ) == true ) with expansion: true == true ------------------------------------------------------------------------------- Parse test names and tags Wildcard at both ends ------------------------------------------------------------------------------- CmdLineTests.cpp: ............................................................................... CmdLineTests.cpp:: PASSED: CHECK( spec.hasFilters() == true ) with expansion: true == true CmdLineTests.cpp:: PASSED: CHECK( spec.matches( tcA ) == false ) with expansion: false == false CmdLineTests.cpp:: PASSED: CHECK( spec.matches( tcB ) == false ) with expansion: false == false CmdLineTests.cpp:: PASSED: CHECK( spec.matches( tcC ) == true ) with expansion: true == true CmdLineTests.cpp:: PASSED: CHECK( spec.matches( tcD ) == true ) with expansion: true == true CmdLineTests.cpp:: PASSED: CHECK( parseTestSpec( "*a*" ).matches( tcA ) == true ) with expansion: true == true ------------------------------------------------------------------------------- Parse test names and tags Redundant wildcard at the start ------------------------------------------------------------------------------- CmdLineTests.cpp: ............................................................................... CmdLineTests.cpp:: PASSED: CHECK( spec.hasFilters() == true ) with expansion: true == true CmdLineTests.cpp:: PASSED: CHECK( spec.matches( tcA ) == true ) with expansion: true == true CmdLineTests.cpp:: PASSED: CHECK( spec.matches( tcB ) == false ) with expansion: false == false ------------------------------------------------------------------------------- Parse test names and tags Redundant wildcard at the end ------------------------------------------------------------------------------- CmdLineTests.cpp: ............................................................................... CmdLineTests.cpp:: PASSED: CHECK( spec.hasFilters() == true ) with expansion: true == true CmdLineTests.cpp:: PASSED: CHECK( spec.matches( tcA ) == true ) with expansion: true == true CmdLineTests.cpp:: PASSED: CHECK( spec.matches( tcB ) == false ) with expansion: false == false ------------------------------------------------------------------------------- Parse test names and tags Redundant wildcard at both ends ------------------------------------------------------------------------------- CmdLineTests.cpp: ............................................................................... CmdLineTests.cpp:: PASSED: CHECK( spec.hasFilters() == true ) with expansion: true == true CmdLineTests.cpp:: PASSED: CHECK( spec.matches( tcA ) == true ) with expansion: true == true CmdLineTests.cpp:: PASSED: CHECK( spec.matches( tcB ) == false ) with expansion: false == false ------------------------------------------------------------------------------- Parse test names and tags Wildcard at both ends, redundant at start ------------------------------------------------------------------------------- CmdLineTests.cpp: ............................................................................... CmdLineTests.cpp:: PASSED: CHECK( spec.hasFilters() == true ) with expansion: true == true CmdLineTests.cpp:: PASSED: CHECK( spec.matches( tcA ) == false ) with expansion: false == false CmdLineTests.cpp:: PASSED: CHECK( spec.matches( tcB ) == false ) with expansion: false == false CmdLineTests.cpp:: PASSED: CHECK( spec.matches( tcC ) == true ) with expansion: true == true CmdLineTests.cpp:: PASSED: CHECK( spec.matches( tcD ) == true ) with expansion: true == true ------------------------------------------------------------------------------- Parse test names and tags Just wildcard ------------------------------------------------------------------------------- CmdLineTests.cpp: ............................................................................... CmdLineTests.cpp:: PASSED: CHECK( spec.hasFilters() == true ) with expansion: true == true CmdLineTests.cpp:: PASSED: CHECK( spec.matches( tcA ) == true ) with expansion: true == true CmdLineTests.cpp:: PASSED: CHECK( spec.matches( tcB ) == true ) with expansion: true == true CmdLineTests.cpp:: PASSED: CHECK( spec.matches( tcC ) == true ) with expansion: true == true CmdLineTests.cpp:: PASSED: CHECK( spec.matches( tcD ) == true ) with expansion: true == true ------------------------------------------------------------------------------- Parse test names and tags Single tag ------------------------------------------------------------------------------- CmdLineTests.cpp: ............................................................................... CmdLineTests.cpp:: PASSED: CHECK( spec.hasFilters() == true ) with expansion: true == true CmdLineTests.cpp:: PASSED: CHECK( spec.matches( tcA ) == false ) with expansion: false == false CmdLineTests.cpp:: PASSED: CHECK( spec.matches( tcB ) == true ) with expansion: true == true CmdLineTests.cpp:: PASSED: CHECK( spec.matches( tcC ) == false ) with expansion: false == false ------------------------------------------------------------------------------- Parse test names and tags Single tag, two matches ------------------------------------------------------------------------------- CmdLineTests.cpp: ............................................................................... CmdLineTests.cpp:: PASSED: CHECK( spec.hasFilters() == true ) with expansion: true == true CmdLineTests.cpp:: PASSED: CHECK( spec.matches( tcA ) == false ) with expansion: false == false CmdLineTests.cpp:: PASSED: CHECK( spec.matches( tcB ) == true ) with expansion: true == true CmdLineTests.cpp:: PASSED: CHECK( spec.matches( tcC ) == true ) with expansion: true == true ------------------------------------------------------------------------------- Parse test names and tags Two tags ------------------------------------------------------------------------------- CmdLineTests.cpp: ............................................................................... CmdLineTests.cpp:: PASSED: CHECK( spec.hasFilters() == true ) with expansion: true == true CmdLineTests.cpp:: PASSED: CHECK( spec.matches( tcA ) == false ) with expansion: false == false CmdLineTests.cpp:: PASSED: CHECK( spec.matches( tcB ) == false ) with expansion: false == false CmdLineTests.cpp:: PASSED: CHECK( spec.matches( tcC ) == true ) with expansion: true == true ------------------------------------------------------------------------------- Parse test names and tags Two tags, spare separated ------------------------------------------------------------------------------- CmdLineTests.cpp: ............................................................................... CmdLineTests.cpp:: PASSED: CHECK( spec.hasFilters() == true ) with expansion: true == true CmdLineTests.cpp:: PASSED: CHECK( spec.matches( tcA ) == false ) with expansion: false == false CmdLineTests.cpp:: PASSED: CHECK( spec.matches( tcB ) == false ) with expansion: false == false CmdLineTests.cpp:: PASSED: CHECK( spec.matches( tcC ) == true ) with expansion: true == true ------------------------------------------------------------------------------- Parse test names and tags Wildcarded name and tag ------------------------------------------------------------------------------- CmdLineTests.cpp: ............................................................................... CmdLineTests.cpp:: PASSED: CHECK( spec.hasFilters() == true ) with expansion: true == true CmdLineTests.cpp:: PASSED: CHECK( spec.matches( tcA ) == false ) with expansion: false == false CmdLineTests.cpp:: PASSED: CHECK( spec.matches( tcB ) == false ) with expansion: false == false CmdLineTests.cpp:: PASSED: CHECK( spec.matches( tcC ) == true ) with expansion: true == true CmdLineTests.cpp:: PASSED: CHECK( spec.matches( tcD ) == false ) with expansion: false == false ------------------------------------------------------------------------------- Parse test names and tags Single tag exclusion ------------------------------------------------------------------------------- CmdLineTests.cpp: ............................................................................... CmdLineTests.cpp:: PASSED: CHECK( spec.hasFilters() == true ) with expansion: true == true CmdLineTests.cpp:: PASSED: CHECK( spec.matches( tcA ) == true ) with expansion: true == true CmdLineTests.cpp:: PASSED: CHECK( spec.matches( tcB ) == false ) with expansion: false == false CmdLineTests.cpp:: PASSED: CHECK( spec.matches( tcC ) == true ) with expansion: true == true ------------------------------------------------------------------------------- Parse test names and tags One tag exclusion and one tag inclusion ------------------------------------------------------------------------------- CmdLineTests.cpp: ............................................................................... CmdLineTests.cpp:: PASSED: CHECK( spec.hasFilters() == true ) with expansion: true == true CmdLineTests.cpp:: PASSED: CHECK( spec.matches( tcA ) == false ) with expansion: false == false CmdLineTests.cpp:: PASSED: CHECK( spec.matches( tcB ) == true ) with expansion: true == true CmdLineTests.cpp:: PASSED: CHECK( spec.matches( tcC ) == false ) with expansion: false == false ------------------------------------------------------------------------------- Parse test names and tags One tag exclusion and one wldcarded name inclusion ------------------------------------------------------------------------------- CmdLineTests.cpp: ............................................................................... CmdLineTests.cpp:: PASSED: CHECK( spec.hasFilters() == true ) with expansion: true == true CmdLineTests.cpp:: PASSED: CHECK( spec.matches( tcA ) == false ) with expansion: false == false CmdLineTests.cpp:: PASSED: CHECK( spec.matches( tcB ) == false ) with expansion: false == false CmdLineTests.cpp:: PASSED: CHECK( spec.matches( tcC ) == false ) with expansion: false == false CmdLineTests.cpp:: PASSED: CHECK( spec.matches( tcD ) == true ) with expansion: true == true ------------------------------------------------------------------------------- Parse test names and tags One tag exclusion, using exclude:, and one wldcarded name inclusion ------------------------------------------------------------------------------- CmdLineTests.cpp: ............................................................................... CmdLineTests.cpp:: PASSED: CHECK( spec.hasFilters() == true ) with expansion: true == true CmdLineTests.cpp:: PASSED: CHECK( spec.matches( tcA ) == false ) with expansion: false == false CmdLineTests.cpp:: PASSED: CHECK( spec.matches( tcB ) == false ) with expansion: false == false CmdLineTests.cpp:: PASSED: CHECK( spec.matches( tcC ) == false ) with expansion: false == false CmdLineTests.cpp:: PASSED: CHECK( spec.matches( tcD ) == true ) with expansion: true == true ------------------------------------------------------------------------------- Parse test names and tags name exclusion ------------------------------------------------------------------------------- CmdLineTests.cpp: ............................................................................... CmdLineTests.cpp:: PASSED: CHECK( spec.hasFilters() == true ) with expansion: true == true CmdLineTests.cpp:: PASSED: CHECK( spec.matches( tcA ) == true ) with expansion: true == true CmdLineTests.cpp:: PASSED: CHECK( spec.matches( tcB ) == false ) with expansion: false == false CmdLineTests.cpp:: PASSED: CHECK( spec.matches( tcC ) == true ) with expansion: true == true CmdLineTests.cpp:: PASSED: CHECK( spec.matches( tcD ) == true ) with expansion: true == true ------------------------------------------------------------------------------- Parse test names and tags wildcarded name exclusion ------------------------------------------------------------------------------- CmdLineTests.cpp: ............................................................................... CmdLineTests.cpp:: PASSED: CHECK( spec.hasFilters() == true ) with expansion: true == true CmdLineTests.cpp:: PASSED: CHECK( spec.matches( tcA ) == true ) with expansion: true == true CmdLineTests.cpp:: PASSED: CHECK( spec.matches( tcB ) == true ) with expansion: true == true CmdLineTests.cpp:: PASSED: CHECK( spec.matches( tcC ) == false ) with expansion: false == false CmdLineTests.cpp:: PASSED: CHECK( spec.matches( tcD ) == false ) with expansion: false == false ------------------------------------------------------------------------------- Parse test names and tags wildcarded name exclusion with tag inclusion ------------------------------------------------------------------------------- CmdLineTests.cpp: ............................................................................... CmdLineTests.cpp:: PASSED: CHECK( spec.hasFilters() == true ) with expansion: true == true CmdLineTests.cpp:: PASSED: CHECK( spec.matches( tcA ) == true ) with expansion: true == true CmdLineTests.cpp:: PASSED: CHECK( spec.matches( tcB ) == true ) with expansion: true == true CmdLineTests.cpp:: PASSED: CHECK( spec.matches( tcC ) == true ) with expansion: true == true CmdLineTests.cpp:: PASSED: CHECK( spec.matches( tcD ) == false ) with expansion: false == false ------------------------------------------------------------------------------- Parse test names and tags wildcarded name exclusion, using exclude:, with tag inclusion ------------------------------------------------------------------------------- CmdLineTests.cpp: ............................................................................... CmdLineTests.cpp:: PASSED: CHECK( spec.hasFilters() == true ) with expansion: true == true CmdLineTests.cpp:: PASSED: CHECK( spec.matches( tcA ) == true ) with expansion: true == true CmdLineTests.cpp:: PASSED: CHECK( spec.matches( tcB ) == true ) with expansion: true == true CmdLineTests.cpp:: PASSED: CHECK( spec.matches( tcC ) == true ) with expansion: true == true CmdLineTests.cpp:: PASSED: CHECK( spec.matches( tcD ) == false ) with expansion: false == false ------------------------------------------------------------------------------- Parse test names and tags two wildcarded names ------------------------------------------------------------------------------- CmdLineTests.cpp: ............................................................................... CmdLineTests.cpp:: PASSED: CHECK( spec.hasFilters() == true ) with expansion: true == true CmdLineTests.cpp:: PASSED: CHECK( spec.matches( tcA ) == false ) with expansion: false == false CmdLineTests.cpp:: PASSED: CHECK( spec.matches( tcB ) == false ) with expansion: false == false CmdLineTests.cpp:: PASSED: CHECK( spec.matches( tcC ) == true ) with expansion: true == true CmdLineTests.cpp:: PASSED: CHECK( spec.matches( tcD ) == false ) with expansion: false == false ------------------------------------------------------------------------------- Parse test names and tags empty tag ------------------------------------------------------------------------------- CmdLineTests.cpp: ............................................................................... CmdLineTests.cpp:: PASSED: CHECK( spec.hasFilters() == false ) with expansion: false == false CmdLineTests.cpp:: PASSED: CHECK( spec.matches( tcA ) == false ) with expansion: false == false CmdLineTests.cpp:: PASSED: CHECK( spec.matches( tcB ) == false ) with expansion: false == false CmdLineTests.cpp:: PASSED: CHECK( spec.matches( tcC ) == false ) with expansion: false == false CmdLineTests.cpp:: PASSED: CHECK( spec.matches( tcD ) == false ) with expansion: false == false ------------------------------------------------------------------------------- Parse test names and tags empty quoted name ------------------------------------------------------------------------------- CmdLineTests.cpp: ............................................................................... CmdLineTests.cpp:: PASSED: CHECK( spec.hasFilters() == false ) with expansion: false == false CmdLineTests.cpp:: PASSED: CHECK( spec.matches( tcA ) == false ) with expansion: false == false CmdLineTests.cpp:: PASSED: CHECK( spec.matches( tcB ) == false ) with expansion: false == false CmdLineTests.cpp:: PASSED: CHECK( spec.matches( tcC ) == false ) with expansion: false == false CmdLineTests.cpp:: PASSED: CHECK( spec.matches( tcD ) == false ) with expansion: false == false ------------------------------------------------------------------------------- Parse test names and tags quoted string followed by tag exclusion ------------------------------------------------------------------------------- CmdLineTests.cpp: ............................................................................... CmdLineTests.cpp:: PASSED: CHECK( spec.hasFilters() == true ) with expansion: true == true CmdLineTests.cpp:: PASSED: CHECK( spec.matches( tcA ) == false ) with expansion: false == false CmdLineTests.cpp:: PASSED: CHECK( spec.matches( tcB ) == false ) with expansion: false == false CmdLineTests.cpp:: PASSED: CHECK( spec.matches( tcC ) == false ) with expansion: false == false CmdLineTests.cpp:: PASSED: CHECK( spec.matches( tcD ) == true ) with expansion: true == true ------------------------------------------------------------------------------- Parsing a std::pair ------------------------------------------------------------------------------- TrickyTests.cpp: ............................................................................... TrickyTests.cpp:: PASSED: REQUIRE( (std::pair( 1, 2 )) == aNicePair ) with expansion: std::pair( 1, 2 ) == std::pair( 1, 2 ) ------------------------------------------------------------------------------- Pointers can be compared to null ------------------------------------------------------------------------------- ConditionTests.cpp: ............................................................................... ConditionTests.cpp:: PASSED: REQUIRE( p == 0 ) with expansion: NULL == 0 ConditionTests.cpp:: PASSED: REQUIRE( p == pNULL ) with expansion: NULL == NULL ConditionTests.cpp:: PASSED: REQUIRE( p != 0 ) with expansion: 0x != 0 ConditionTests.cpp:: PASSED: REQUIRE( cp != 0 ) with expansion: 0x != 0 ConditionTests.cpp:: PASSED: REQUIRE( cpc != 0 ) with expansion: 0x != 0 ConditionTests.cpp:: PASSED: REQUIRE( returnsNull() == 0 ) with expansion: {null string} == 0 ConditionTests.cpp:: PASSED: REQUIRE( returnsConstNull() == 0 ) with expansion: {null string} == 0 ConditionTests.cpp:: PASSED: REQUIRE( 0 != p ) with expansion: 0 != 0x ------------------------------------------------------------------------------- Pointers can be converted to strings ------------------------------------------------------------------------------- MessageTests.cpp: ............................................................................... MessageTests.cpp:: warning: actual address of p: 0x MessageTests.cpp:: warning: toString(p): 0x ------------------------------------------------------------------------------- Process can be configured on command line empty args don't cause a crash ------------------------------------------------------------------------------- TestMain.cpp: ............................................................................... TestMain.cpp:: PASSED: CHECK_NOTHROW( parser.parseInto( std::vector(), config ) ) TestMain.cpp:: PASSED: CHECK( config.processName == "" ) with expansion: "" == "" ------------------------------------------------------------------------------- Process can be configured on command line default - no arguments ------------------------------------------------------------------------------- TestMain.cpp: ............................................................................... TestMain.cpp:: PASSED: CHECK_NOTHROW( parseIntoConfig( argv, config ) ) TestMain.cpp:: PASSED: CHECK( config.processName == "test" ) with expansion: "test" == "test" TestMain.cpp:: PASSED: CHECK( config.shouldDebugBreak == false ) with expansion: false == false TestMain.cpp:: PASSED: CHECK( config.abortAfter == -1 ) with expansion: -1 == -1 TestMain.cpp:: PASSED: CHECK( config.noThrow == false ) with expansion: false == false TestMain.cpp:: PASSED: CHECK( config.reporterNames.empty() ) with expansion: true ------------------------------------------------------------------------------- Process can be configured on command line test lists 1 test ------------------------------------------------------------------------------- TestMain.cpp: ............................................................................... TestMain.cpp:: PASSED: CHECK_NOTHROW( parseIntoConfig( argv, config ) ) TestMain.cpp:: PASSED: REQUIRE( cfg.testSpec().matches( fakeTestCase( "notIncluded" ) ) == false ) with expansion: false == false TestMain.cpp:: PASSED: REQUIRE( cfg.testSpec().matches( fakeTestCase( "test1" ) ) ) with expansion: true ------------------------------------------------------------------------------- Process can be configured on command line test lists Specify one test case exclusion using exclude: ------------------------------------------------------------------------------- TestMain.cpp: ............................................................................... TestMain.cpp:: PASSED: CHECK_NOTHROW( parseIntoConfig( argv, config ) ) TestMain.cpp:: PASSED: REQUIRE( cfg.testSpec().matches( fakeTestCase( "test1" ) ) == false ) with expansion: false == false TestMain.cpp:: PASSED: REQUIRE( cfg.testSpec().matches( fakeTestCase( "alwaysIncluded" ) ) ) with expansion: true ------------------------------------------------------------------------------- Process can be configured on command line test lists Specify one test case exclusion using ~ ------------------------------------------------------------------------------- TestMain.cpp: ............................................................................... TestMain.cpp:: PASSED: CHECK_NOTHROW( parseIntoConfig( argv, config ) ) TestMain.cpp:: PASSED: REQUIRE( cfg.testSpec().matches( fakeTestCase( "test1" ) ) == false ) with expansion: false == false TestMain.cpp:: PASSED: REQUIRE( cfg.testSpec().matches( fakeTestCase( "alwaysIncluded" ) ) ) with expansion: true ------------------------------------------------------------------------------- Process can be configured on command line reporter -r/console ------------------------------------------------------------------------------- TestMain.cpp: ............................................................................... TestMain.cpp:: PASSED: CHECK_NOTHROW( parseIntoConfig( argv, config ) ) TestMain.cpp:: PASSED: REQUIRE( config.reporterNames[0] == "console" ) with expansion: "console" == "console" ------------------------------------------------------------------------------- Process can be configured on command line reporter -r/xml ------------------------------------------------------------------------------- TestMain.cpp: ............................................................................... TestMain.cpp:: PASSED: CHECK_NOTHROW( parseIntoConfig( argv, config ) ) TestMain.cpp:: PASSED: REQUIRE( config.reporterNames[0] == "xml" ) with expansion: "xml" == "xml" ------------------------------------------------------------------------------- Process can be configured on command line reporter -r xml and junit ------------------------------------------------------------------------------- TestMain.cpp: ............................................................................... TestMain.cpp:: PASSED: CHECK_NOTHROW( parseIntoConfig( argv, config ) ) TestMain.cpp:: PASSED: REQUIRE( config.reporterNames.size() == 2 ) with expansion: 2 == 2 TestMain.cpp:: PASSED: REQUIRE( config.reporterNames[0] == "xml" ) with expansion: "xml" == "xml" TestMain.cpp:: PASSED: REQUIRE( config.reporterNames[1] == "junit" ) with expansion: "junit" == "junit" ------------------------------------------------------------------------------- Process can be configured on command line reporter --reporter/junit ------------------------------------------------------------------------------- TestMain.cpp: ............................................................................... TestMain.cpp:: PASSED: CHECK_NOTHROW( parseIntoConfig( argv, config ) ) TestMain.cpp:: PASSED: REQUIRE( config.reporterNames[0] == "junit" ) with expansion: "junit" == "junit" ------------------------------------------------------------------------------- Process can be configured on command line debugger -b ------------------------------------------------------------------------------- TestMain.cpp: ............................................................................... TestMain.cpp:: PASSED: CHECK_NOTHROW( parseIntoConfig( argv, config ) ) TestMain.cpp:: PASSED: REQUIRE( config.shouldDebugBreak == true ) with expansion: true == true ------------------------------------------------------------------------------- Process can be configured on command line debugger --break ------------------------------------------------------------------------------- TestMain.cpp: ............................................................................... TestMain.cpp:: PASSED: CHECK_NOTHROW( parseIntoConfig( argv, config ) ) TestMain.cpp:: PASSED: REQUIRE( config.shouldDebugBreak ) with expansion: true ------------------------------------------------------------------------------- Process can be configured on command line abort -a aborts after first failure ------------------------------------------------------------------------------- TestMain.cpp: ............................................................................... TestMain.cpp:: PASSED: CHECK_NOTHROW( parseIntoConfig( argv, config ) ) TestMain.cpp:: PASSED: REQUIRE( config.abortAfter == 1 ) with expansion: 1 == 1 ------------------------------------------------------------------------------- Process can be configured on command line abort -x 2 aborts after two failures ------------------------------------------------------------------------------- TestMain.cpp: ............................................................................... TestMain.cpp:: PASSED: CHECK_NOTHROW( parseIntoConfig( argv, config ) ) TestMain.cpp:: PASSED: REQUIRE( config.abortAfter == 2 ) with expansion: 2 == 2 ------------------------------------------------------------------------------- Process can be configured on command line abort -x must be greater than zero ------------------------------------------------------------------------------- TestMain.cpp: ............................................................................... TestMain.cpp:: PASSED: REQUIRE_THAT( parseIntoConfigAndReturnError( argv, config ), Contains( "greater than zero" ) ) with expansion: "Value after -x or --abortAfter must be greater than zero - while parsing: (-x, --abortx )" contains: "greater than zero" ------------------------------------------------------------------------------- Process can be configured on command line abort -x must be numeric ------------------------------------------------------------------------------- TestMain.cpp: ............................................................................... TestMain.cpp:: PASSED: REQUIRE_THAT( parseIntoConfigAndReturnError( argv, config ), Contains( "-x" ) ) with expansion: "Unable to convert oops to destination type - while parsing: (-x, --abortx )" contains: "-x" ------------------------------------------------------------------------------- Process can be configured on command line nothrow -e ------------------------------------------------------------------------------- TestMain.cpp: ............................................................................... TestMain.cpp:: PASSED: CHECK_NOTHROW( parseIntoConfig( argv, config ) ) TestMain.cpp:: PASSED: REQUIRE( config.noThrow == true ) with expansion: true == true ------------------------------------------------------------------------------- Process can be configured on command line nothrow --nothrow ------------------------------------------------------------------------------- TestMain.cpp: ............................................................................... TestMain.cpp:: PASSED: CHECK_NOTHROW( parseIntoConfig( argv, config ) ) TestMain.cpp:: PASSED: REQUIRE( config.noThrow == true ) with expansion: true == true ------------------------------------------------------------------------------- Process can be configured on command line output filename -o filename ------------------------------------------------------------------------------- TestMain.cpp: ............................................................................... TestMain.cpp:: PASSED: CHECK_NOTHROW( parseIntoConfig( argv, config ) ) TestMain.cpp:: PASSED: REQUIRE( config.outputFilename == "filename.ext" ) with expansion: "filename.ext" == "filename.ext" ------------------------------------------------------------------------------- Process can be configured on command line output filename --out ------------------------------------------------------------------------------- TestMain.cpp: ............................................................................... TestMain.cpp:: PASSED: CHECK_NOTHROW( parseIntoConfig( argv, config ) ) TestMain.cpp:: PASSED: REQUIRE( config.outputFilename == "filename.ext" ) with expansion: "filename.ext" == "filename.ext" ------------------------------------------------------------------------------- Process can be configured on command line combinations Single character flags can be combined ------------------------------------------------------------------------------- TestMain.cpp: ............................................................................... TestMain.cpp:: PASSED: CHECK_NOTHROW( parseIntoConfig( argv, config ) ) TestMain.cpp:: PASSED: CHECK( config.abortAfter == 1 ) with expansion: 1 == 1 TestMain.cpp:: PASSED: CHECK( config.shouldDebugBreak ) with expansion: true TestMain.cpp:: PASSED: CHECK( config.noThrow == true ) with expansion: true == true ------------------------------------------------------------------------------- Process can be configured on command line use-colour without option ------------------------------------------------------------------------------- TestMain.cpp: ............................................................................... TestMain.cpp:: PASSED: CHECK_NOTHROW( parseIntoConfig( argv, config ) ) TestMain.cpp:: PASSED: REQUIRE( config.useColour == UseColour::Auto ) with expansion: 0 == 0 ------------------------------------------------------------------------------- Process can be configured on command line use-colour auto ------------------------------------------------------------------------------- TestMain.cpp: ............................................................................... TestMain.cpp:: PASSED: CHECK_NOTHROW( parseIntoConfig( argv, config ) ) TestMain.cpp:: PASSED: REQUIRE( config.useColour == UseColour::Auto ) with expansion: 0 == 0 ------------------------------------------------------------------------------- Process can be configured on command line use-colour yes ------------------------------------------------------------------------------- TestMain.cpp: ............................................................................... TestMain.cpp:: PASSED: CHECK_NOTHROW( parseIntoConfig( argv, config ) ) TestMain.cpp:: PASSED: REQUIRE( config.useColour == UseColour::Yes ) with expansion: 1 == 1 ------------------------------------------------------------------------------- Process can be configured on command line use-colour no ------------------------------------------------------------------------------- TestMain.cpp: ............................................................................... TestMain.cpp:: PASSED: CHECK_NOTHROW( parseIntoConfig( argv, config ) ) TestMain.cpp:: PASSED: REQUIRE( config.useColour == UseColour::No ) with expansion: 2 == 2 ------------------------------------------------------------------------------- Process can be configured on command line use-colour error ------------------------------------------------------------------------------- TestMain.cpp: ............................................................................... TestMain.cpp:: PASSED: REQUIRE_THROWS_WITH( parseIntoConfig( argv, config ), Contains( "colour mode must be one of" ) ) ------------------------------------------------------------------------------- Reconstruction should be based on stringification: #914 ------------------------------------------------------------------------------- DecompositionTests.cpp: ............................................................................... DecompositionTests.cpp:: FAILED: CHECK( truthy(false) ) with expansion: Hey, its truthy! ------------------------------------------------------------------------------- SCOPED_INFO is reset for each loop ------------------------------------------------------------------------------- MessageTests.cpp: ............................................................................... MessageTests.cpp:: PASSED: REQUIRE( i < 10 ) with expansion: 0 < 10 with messages: current counter 0 i := 0 MessageTests.cpp:: PASSED: REQUIRE( i < 10 ) with expansion: 1 < 10 with messages: current counter 1 i := 1 MessageTests.cpp:: PASSED: REQUIRE( i < 10 ) with expansion: 2 < 10 with messages: current counter 2 i := 2 MessageTests.cpp:: PASSED: REQUIRE( i < 10 ) with expansion: 3 < 10 with messages: current counter 3 i := 3 MessageTests.cpp:: PASSED: REQUIRE( i < 10 ) with expansion: 4 < 10 with messages: current counter 4 i := 4 MessageTests.cpp:: PASSED: REQUIRE( i < 10 ) with expansion: 5 < 10 with messages: current counter 5 i := 5 MessageTests.cpp:: PASSED: REQUIRE( i < 10 ) with expansion: 6 < 10 with messages: current counter 6 i := 6 MessageTests.cpp:: PASSED: REQUIRE( i < 10 ) with expansion: 7 < 10 with messages: current counter 7 i := 7 MessageTests.cpp:: PASSED: REQUIRE( i < 10 ) with expansion: 8 < 10 with messages: current counter 8 i := 8 MessageTests.cpp:: PASSED: REQUIRE( i < 10 ) with expansion: 9 < 10 with messages: current counter 9 i := 9 MessageTests.cpp:: FAILED: REQUIRE( i < 10 ) with expansion: 10 < 10 with messages: current counter 10 i := 10 ------------------------------------------------------------------------------- SUCCEED counts as a test pass ------------------------------------------------------------------------------- MessageTests.cpp: ............................................................................... MessageTests.cpp:: PASSED: with message: this is a success ------------------------------------------------------------------------------- SUCCESS does not require an argument ------------------------------------------------------------------------------- MessageTests.cpp: ............................................................................... MessageTests.cpp:: PASSED: ------------------------------------------------------------------------------- Scenario: BDD tests requiring Fixtures to provide commonly-accessed data or methods Given: No operations precede me ------------------------------------------------------------------------------- BDDTests.cpp: ............................................................................... BDDTests.cpp:: PASSED: REQUIRE( before == 0 ) with expansion: 0 == 0 ------------------------------------------------------------------------------- Scenario: BDD tests requiring Fixtures to provide commonly-accessed data or methods Given: No operations precede me When: We get the count Then: Subsequently values are higher ------------------------------------------------------------------------------- BDDTests.cpp: ............................................................................... BDDTests.cpp:: PASSED: REQUIRE( after > before ) with expansion: 1 > 0 ------------------------------------------------------------------------------- Scenario: Do that thing with the thing Given: This stuff exists When: I do this Then: it should do this ------------------------------------------------------------------------------- BDDTests.cpp: ............................................................................... BDDTests.cpp:: PASSED: REQUIRE( itDoesThis() ) with expansion: true ------------------------------------------------------------------------------- Scenario: Do that thing with the thing Given: This stuff exists When: I do this Then: it should do this And: do that ------------------------------------------------------------------------------- BDDTests.cpp: ............................................................................... BDDTests.cpp:: PASSED: REQUIRE( itDoesThat() ) with expansion: true ------------------------------------------------------------------------------- Scenario: This is a really long scenario name to see how the list command deals with wrapping Given: A section name that is so long that it cannot fit in a single console width When: The test headers are printed as part of the normal running of the scenario Then: The, deliberately very long and overly verbose (you see what I did there?) section names must wrap, along with an indent ------------------------------------------------------------------------------- BDDTests.cpp: ............................................................................... BDDTests.cpp:: PASSED: with message: boo! ------------------------------------------------------------------------------- Scenario: Vector resizing affects size and capacity Given: an empty vector ------------------------------------------------------------------------------- BDDTests.cpp: ............................................................................... BDDTests.cpp:: PASSED: REQUIRE( v.size() == 0 ) with expansion: 0 == 0 ------------------------------------------------------------------------------- Scenario: Vector resizing affects size and capacity Given: an empty vector When: it is made larger Then: the size and capacity go up ------------------------------------------------------------------------------- BDDTests.cpp: ............................................................................... BDDTests.cpp:: PASSED: REQUIRE( v.size() == 10 ) with expansion: 10 == 10 BDDTests.cpp:: PASSED: REQUIRE( v.capacity() >= 10 ) with expansion: 10 >= 10 ------------------------------------------------------------------------------- Scenario: Vector resizing affects size and capacity Given: an empty vector When: it is made larger Then: the size and capacity go up And when: it is made smaller again Then: the size goes down but the capacity stays the same ------------------------------------------------------------------------------- BDDTests.cpp: ............................................................................... BDDTests.cpp:: PASSED: REQUIRE( v.size() == 5 ) with expansion: 5 == 5 BDDTests.cpp:: PASSED: REQUIRE( v.capacity() >= 10 ) with expansion: 10 >= 10 ------------------------------------------------------------------------------- Scenario: Vector resizing affects size and capacity Given: an empty vector ------------------------------------------------------------------------------- BDDTests.cpp: ............................................................................... BDDTests.cpp:: PASSED: REQUIRE( v.size() == 0 ) with expansion: 0 == 0 ------------------------------------------------------------------------------- Scenario: Vector resizing affects size and capacity Given: an empty vector When: we reserve more space Then: The capacity is increased but the size remains the same ------------------------------------------------------------------------------- BDDTests.cpp: ............................................................................... BDDTests.cpp:: PASSED: REQUIRE( v.capacity() >= 10 ) with expansion: 10 >= 10 BDDTests.cpp:: PASSED: REQUIRE( v.size() == 0 ) with expansion: 0 == 0 A string sent directly to stdout A string sent directly to stderr ------------------------------------------------------------------------------- Some simple comparisons between doubles ------------------------------------------------------------------------------- ApproxTests.cpp: ............................................................................... ApproxTests.cpp:: PASSED: REQUIRE( d == Approx( 1.23 ) ) with expansion: 1.23 == Approx( 1.23 ) ApproxTests.cpp:: PASSED: REQUIRE( d != Approx( 1.22 ) ) with expansion: 1.23 != Approx( 1.22 ) ApproxTests.cpp:: PASSED: REQUIRE( d != Approx( 1.24 ) ) with expansion: 1.23 != Approx( 1.24 ) ApproxTests.cpp:: PASSED: REQUIRE( Approx( d ) == 1.23 ) with expansion: Approx( 1.23 ) == 1.23 ApproxTests.cpp:: PASSED: REQUIRE( Approx( d ) != 1.22 ) with expansion: Approx( 1.23 ) != 1.22 ApproxTests.cpp:: PASSED: REQUIRE( Approx( d ) != 1.24 ) with expansion: Approx( 1.23 ) != 1.24 ApproxTests.cpp:: PASSED: REQUIRE( 0 == Approx(0) ) with expansion: 0 == Approx( 0.0 ) Write to std::cerr ------------------------------------------------------------------------------- Standard error is reported and redirected std::cerr ------------------------------------------------------------------------------- MessageTests.cpp: ............................................................................... No assertions in section 'std::cerr' Write to std::clog ------------------------------------------------------------------------------- Standard error is reported and redirected std::clog ------------------------------------------------------------------------------- MessageTests.cpp: ............................................................................... No assertions in section 'std::clog' Interleaved writes to error streams ------------------------------------------------------------------------------- Standard error is reported and redirected Interleaved writes to cerr and clog ------------------------------------------------------------------------------- MessageTests.cpp: ............................................................................... No assertions in section 'Interleaved writes to cerr and clog' Message from section one ------------------------------------------------------------------------------- Standard output from all sections is reported one ------------------------------------------------------------------------------- MessageTests.cpp: ............................................................................... No assertions in section 'one' Message from section two ------------------------------------------------------------------------------- Standard output from all sections is reported two ------------------------------------------------------------------------------- MessageTests.cpp: ............................................................................... No assertions in section 'two' ------------------------------------------------------------------------------- StartsWith string matcher ------------------------------------------------------------------------------- MatchersTests.cpp: ............................................................................... MatchersTests.cpp:: FAILED: CHECK_THAT( testStringForMatching(), StartsWith( "string" ) ) with expansion: "this string contains 'abc' as a substring" starts with: "string" ------------------------------------------------------------------------------- String matchers ------------------------------------------------------------------------------- MatchersTests.cpp: ............................................................................... MatchersTests.cpp:: PASSED: REQUIRE_THAT( testStringForMatching(), Contains( "string" ) ) with expansion: "this string contains 'abc' as a substring" contains: "string" MatchersTests.cpp:: PASSED: CHECK_THAT( testStringForMatching(), Contains( "abc" ) ) with expansion: "this string contains 'abc' as a substring" contains: "abc" MatchersTests.cpp:: PASSED: CHECK_THAT( testStringForMatching(), StartsWith( "this" ) ) with expansion: "this string contains 'abc' as a substring" starts with: "this" MatchersTests.cpp:: PASSED: CHECK_THAT( testStringForMatching(), EndsWith( "substring" ) ) with expansion: "this string contains 'abc' as a substring" ends with: "substring" hello hello ------------------------------------------------------------------------------- Tabs and newlines show in output ------------------------------------------------------------------------------- MiscTests.cpp: ............................................................................... MiscTests.cpp:: FAILED: CHECK( s1 == s2 ) with expansion: "if ($b == 10) { $a = 20; }" == "if ($b == 10) { $a = 20; } " ------------------------------------------------------------------------------- Tag alias can be registered against tag patterns The same tag alias can only be registered once ------------------------------------------------------------------------------- TagAliasTests.cpp: ............................................................................... TagAliasTests.cpp:: PASSED: CHECK_THAT( what, Contains( "[@zzz]" ) ) with expansion: "error: tag alias, "[@zzz]" already registered. First seen at file:2 Redefined at file:10 " contains: "[@zzz]" TagAliasTests.cpp:: PASSED: CHECK_THAT( what, Contains( "file" ) ) with expansion: "error: tag alias, "[@zzz]" already registered. First seen at file:2 Redefined at file:10 " contains: "file" TagAliasTests.cpp:: PASSED: CHECK_THAT( what, Contains( "2" ) ) with expansion: "error: tag alias, "[@zzz]" already registered. First seen at file:2 Redefined at file:10 " contains: "2" TagAliasTests.cpp:: PASSED: CHECK_THAT( what, Contains( "10" ) ) with expansion: "error: tag alias, "[@zzz]" already registered. First seen at file:2 Redefined at file:10 " contains: "10" ------------------------------------------------------------------------------- Tag alias can be registered against tag patterns Tag aliases must be of the form [@name] ------------------------------------------------------------------------------- TagAliasTests.cpp: ............................................................................... TagAliasTests.cpp:: PASSED: CHECK_THROWS( registry.add( "[no ampersat]", "", Catch::SourceLineInfo( "file", 3 ) ) ) TagAliasTests.cpp:: PASSED: CHECK_THROWS( registry.add( "[the @ is not at the start]", "", Catch::SourceLineInfo( "file", 3 ) ) ) TagAliasTests.cpp:: PASSED: CHECK_THROWS( registry.add( "@no square bracket at start]", "", Catch::SourceLineInfo( "file", 3 ) ) ) TagAliasTests.cpp:: PASSED: CHECK_THROWS( registry.add( "[@no square bracket at end", "", Catch::SourceLineInfo( "file", 3 ) ) ) ------------------------------------------------------------------------------- Test case with one argument ------------------------------------------------------------------------------- VariadicMacrosTests.cpp: ............................................................................... VariadicMacrosTests.cpp:: PASSED: with message: no assertions ------------------------------------------------------------------------------- Test enum bit values ------------------------------------------------------------------------------- TrickyTests.cpp: ............................................................................... TrickyTests.cpp:: PASSED: REQUIRE( 0x == bit30and31 ) with expansion: 3221225472 (0x) == 3221225472 ------------------------------------------------------------------------------- Text can be formatted using the Text class ------------------------------------------------------------------------------- TestMain.cpp: ............................................................................... TestMain.cpp:: PASSED: CHECK( Text( "hi there" ).toString() == "hi there" ) with expansion: "hi there" == "hi there" TestMain.cpp:: PASSED: CHECK( Text( "hi there", narrow ).toString() == "hi\nthere" ) with expansion: "hi there" == "hi there" ------------------------------------------------------------------------------- The NO_FAIL macro reports a failure but does not fail the test ------------------------------------------------------------------------------- MessageTests.cpp: ............................................................................... MessageTests.cpp:: FAILED - but was ok: CHECK_NOFAIL( 1 == 2 ) ------------------------------------------------------------------------------- This test 'should' fail but doesn't ------------------------------------------------------------------------------- MiscTests.cpp: ............................................................................... MiscTests.cpp:: PASSED: with message: oops! ------------------------------------------------------------------------------- Tracker ------------------------------------------------------------------------------- PartTrackerTests.cpp: ............................................................................... PartTrackerTests.cpp:: PASSED: REQUIRE( testCase.isOpen() ) with expansion: true PartTrackerTests.cpp:: PASSED: REQUIRE( s1.isOpen() ) with expansion: true ------------------------------------------------------------------------------- Tracker successfully close one section ------------------------------------------------------------------------------- PartTrackerTests.cpp: ............................................................................... PartTrackerTests.cpp:: PASSED: REQUIRE( s1.isSuccessfullyCompleted() ) with expansion: true PartTrackerTests.cpp:: PASSED: REQUIRE( testCase.isComplete() == false ) with expansion: false == false PartTrackerTests.cpp:: PASSED: REQUIRE( ctx.completedCycle() ) with expansion: true PartTrackerTests.cpp:: PASSED: REQUIRE( testCase.isSuccessfullyCompleted() ) with expansion: true ------------------------------------------------------------------------------- Tracker ------------------------------------------------------------------------------- PartTrackerTests.cpp: ............................................................................... PartTrackerTests.cpp:: PASSED: REQUIRE( testCase.isOpen() ) with expansion: true PartTrackerTests.cpp:: PASSED: REQUIRE( s1.isOpen() ) with expansion: true ------------------------------------------------------------------------------- Tracker fail one section ------------------------------------------------------------------------------- PartTrackerTests.cpp: ............................................................................... PartTrackerTests.cpp:: PASSED: REQUIRE( s1.isComplete() ) with expansion: true PartTrackerTests.cpp:: PASSED: REQUIRE( s1.isSuccessfullyCompleted() == false ) with expansion: false == false PartTrackerTests.cpp:: PASSED: REQUIRE( testCase.isComplete() == false ) with expansion: false == false PartTrackerTests.cpp:: PASSED: REQUIRE( ctx.completedCycle() ) with expansion: true PartTrackerTests.cpp:: PASSED: REQUIRE( testCase.isSuccessfullyCompleted() == false ) with expansion: false == false ------------------------------------------------------------------------------- Tracker fail one section re-enter after failed section ------------------------------------------------------------------------------- PartTrackerTests.cpp: ............................................................................... PartTrackerTests.cpp:: PASSED: REQUIRE( testCase2.isOpen() ) with expansion: true PartTrackerTests.cpp:: PASSED: REQUIRE( s1b.isOpen() == false ) with expansion: false == false PartTrackerTests.cpp:: PASSED: REQUIRE( ctx.completedCycle() ) with expansion: true PartTrackerTests.cpp:: PASSED: REQUIRE( testCase.isComplete() ) with expansion: true PartTrackerTests.cpp:: PASSED: REQUIRE( testCase.isSuccessfullyCompleted() ) with expansion: true ------------------------------------------------------------------------------- Tracker ------------------------------------------------------------------------------- PartTrackerTests.cpp: ............................................................................... PartTrackerTests.cpp:: PASSED: REQUIRE( testCase.isOpen() ) with expansion: true PartTrackerTests.cpp:: PASSED: REQUIRE( s1.isOpen() ) with expansion: true ------------------------------------------------------------------------------- Tracker fail one section ------------------------------------------------------------------------------- PartTrackerTests.cpp: ............................................................................... PartTrackerTests.cpp:: PASSED: REQUIRE( s1.isComplete() ) with expansion: true PartTrackerTests.cpp:: PASSED: REQUIRE( s1.isSuccessfullyCompleted() == false ) with expansion: false == false PartTrackerTests.cpp:: PASSED: REQUIRE( testCase.isComplete() == false ) with expansion: false == false PartTrackerTests.cpp:: PASSED: REQUIRE( ctx.completedCycle() ) with expansion: true PartTrackerTests.cpp:: PASSED: REQUIRE( testCase.isSuccessfullyCompleted() == false ) with expansion: false == false ------------------------------------------------------------------------------- Tracker fail one section re-enter after failed section and find next section ------------------------------------------------------------------------------- PartTrackerTests.cpp: ............................................................................... PartTrackerTests.cpp:: PASSED: REQUIRE( testCase2.isOpen() ) with expansion: true PartTrackerTests.cpp:: PASSED: REQUIRE( s1b.isOpen() == false ) with expansion: false == false PartTrackerTests.cpp:: PASSED: REQUIRE( s2.isOpen() ) with expansion: true PartTrackerTests.cpp:: PASSED: REQUIRE( ctx.completedCycle() ) with expansion: true PartTrackerTests.cpp:: PASSED: REQUIRE( testCase.isComplete() ) with expansion: true PartTrackerTests.cpp:: PASSED: REQUIRE( testCase.isSuccessfullyCompleted() ) with expansion: true ------------------------------------------------------------------------------- Tracker ------------------------------------------------------------------------------- PartTrackerTests.cpp: ............................................................................... PartTrackerTests.cpp:: PASSED: REQUIRE( testCase.isOpen() ) with expansion: true PartTrackerTests.cpp:: PASSED: REQUIRE( s1.isOpen() ) with expansion: true ------------------------------------------------------------------------------- Tracker successfully close one section, then find another ------------------------------------------------------------------------------- PartTrackerTests.cpp: ............................................................................... PartTrackerTests.cpp:: PASSED: REQUIRE( s2.isOpen() == false ) with expansion: false == false PartTrackerTests.cpp:: PASSED: REQUIRE( testCase.isComplete() == false ) with expansion: false == false ------------------------------------------------------------------------------- Tracker successfully close one section, then find another Re-enter - skips S1 and enters S2 ------------------------------------------------------------------------------- PartTrackerTests.cpp: ............................................................................... PartTrackerTests.cpp:: PASSED: REQUIRE( testCase2.isOpen() ) with expansion: true PartTrackerTests.cpp:: PASSED: REQUIRE( s1b.isOpen() == false ) with expansion: false == false PartTrackerTests.cpp:: PASSED: REQUIRE( s2b.isOpen() ) with expansion: true PartTrackerTests.cpp:: PASSED: REQUIRE( ctx.completedCycle() == false ) with expansion: false == false ------------------------------------------------------------------------------- Tracker successfully close one section, then find another Re-enter - skips S1 and enters S2 Successfully close S2 ------------------------------------------------------------------------------- PartTrackerTests.cpp: ............................................................................... PartTrackerTests.cpp:: PASSED: REQUIRE( ctx.completedCycle() ) with expansion: true PartTrackerTests.cpp:: PASSED: REQUIRE( s2b.isSuccessfullyCompleted() ) with expansion: true PartTrackerTests.cpp:: PASSED: REQUIRE( testCase2.isComplete() == false ) with expansion: false == false PartTrackerTests.cpp:: PASSED: REQUIRE( testCase2.isSuccessfullyCompleted() ) with expansion: true ------------------------------------------------------------------------------- Tracker ------------------------------------------------------------------------------- PartTrackerTests.cpp: ............................................................................... PartTrackerTests.cpp:: PASSED: REQUIRE( testCase.isOpen() ) with expansion: true PartTrackerTests.cpp:: PASSED: REQUIRE( s1.isOpen() ) with expansion: true ------------------------------------------------------------------------------- Tracker successfully close one section, then find another ------------------------------------------------------------------------------- PartTrackerTests.cpp: ............................................................................... PartTrackerTests.cpp:: PASSED: REQUIRE( s2.isOpen() == false ) with expansion: false == false PartTrackerTests.cpp:: PASSED: REQUIRE( testCase.isComplete() == false ) with expansion: false == false ------------------------------------------------------------------------------- Tracker successfully close one section, then find another Re-enter - skips S1 and enters S2 ------------------------------------------------------------------------------- PartTrackerTests.cpp: ............................................................................... PartTrackerTests.cpp:: PASSED: REQUIRE( testCase2.isOpen() ) with expansion: true PartTrackerTests.cpp:: PASSED: REQUIRE( s1b.isOpen() == false ) with expansion: false == false PartTrackerTests.cpp:: PASSED: REQUIRE( s2b.isOpen() ) with expansion: true PartTrackerTests.cpp:: PASSED: REQUIRE( ctx.completedCycle() == false ) with expansion: false == false ------------------------------------------------------------------------------- Tracker successfully close one section, then find another Re-enter - skips S1 and enters S2 fail S2 ------------------------------------------------------------------------------- PartTrackerTests.cpp: ............................................................................... PartTrackerTests.cpp:: PASSED: REQUIRE( ctx.completedCycle() ) with expansion: true PartTrackerTests.cpp:: PASSED: REQUIRE( s2b.isComplete() ) with expansion: true PartTrackerTests.cpp:: PASSED: REQUIRE( s2b.isSuccessfullyCompleted() == false ) with expansion: false == false PartTrackerTests.cpp:: PASSED: REQUIRE( testCase2.isSuccessfullyCompleted() == false ) with expansion: false == false PartTrackerTests.cpp:: PASSED: REQUIRE( testCase3.isOpen() ) with expansion: true PartTrackerTests.cpp:: PASSED: REQUIRE( s1c.isOpen() == false ) with expansion: false == false PartTrackerTests.cpp:: PASSED: REQUIRE( s2c.isOpen() == false ) with expansion: false == false PartTrackerTests.cpp:: PASSED: REQUIRE( testCase3.isSuccessfullyCompleted() ) with expansion: true ------------------------------------------------------------------------------- Tracker ------------------------------------------------------------------------------- PartTrackerTests.cpp: ............................................................................... PartTrackerTests.cpp:: PASSED: REQUIRE( testCase.isOpen() ) with expansion: true PartTrackerTests.cpp:: PASSED: REQUIRE( s1.isOpen() ) with expansion: true ------------------------------------------------------------------------------- Tracker open a nested section ------------------------------------------------------------------------------- PartTrackerTests.cpp: ............................................................................... PartTrackerTests.cpp:: PASSED: REQUIRE( s2.isOpen() ) with expansion: true PartTrackerTests.cpp:: PASSED: REQUIRE( s2.isComplete() ) with expansion: true PartTrackerTests.cpp:: PASSED: REQUIRE( s1.isComplete() == false ) with expansion: false == false PartTrackerTests.cpp:: PASSED: REQUIRE( s1.isComplete() ) with expansion: true PartTrackerTests.cpp:: PASSED: REQUIRE( testCase.isComplete() == false ) with expansion: false == false PartTrackerTests.cpp:: PASSED: REQUIRE( testCase.isComplete() ) with expansion: true ------------------------------------------------------------------------------- Tracker ------------------------------------------------------------------------------- PartTrackerTests.cpp: ............................................................................... PartTrackerTests.cpp:: PASSED: REQUIRE( testCase.isOpen() ) with expansion: true PartTrackerTests.cpp:: PASSED: REQUIRE( s1.isOpen() ) with expansion: true ------------------------------------------------------------------------------- Tracker start a generator ------------------------------------------------------------------------------- PartTrackerTests.cpp: ............................................................................... PartTrackerTests.cpp:: PASSED: REQUIRE( g1.isOpen() ) with expansion: true PartTrackerTests.cpp:: PASSED: REQUIRE( g1.index() == 0 ) with expansion: 0 == 0 PartTrackerTests.cpp:: PASSED: REQUIRE( g1.isComplete() == false ) with expansion: false == false PartTrackerTests.cpp:: PASSED: REQUIRE( s1.isComplete() == false ) with expansion: false == false ------------------------------------------------------------------------------- Tracker start a generator close outer section ------------------------------------------------------------------------------- PartTrackerTests.cpp: ............................................................................... PartTrackerTests.cpp:: PASSED: REQUIRE( s1.isComplete() == false ) with expansion: false == false PartTrackerTests.cpp:: PASSED: REQUIRE( testCase.isSuccessfullyCompleted() == false ) with expansion: false == false ------------------------------------------------------------------------------- Tracker start a generator close outer section Re-enter for second generation ------------------------------------------------------------------------------- PartTrackerTests.cpp: ............................................................................... PartTrackerTests.cpp:: PASSED: REQUIRE( testCase2.isOpen() ) with expansion: true PartTrackerTests.cpp:: PASSED: REQUIRE( s1b.isOpen() ) with expansion: true PartTrackerTests.cpp:: PASSED: REQUIRE( g1b.isOpen() ) with expansion: true PartTrackerTests.cpp:: PASSED: REQUIRE( g1b.index() == 1 ) with expansion: 1 == 1 PartTrackerTests.cpp:: PASSED: REQUIRE( s1.isComplete() == false ) with expansion: false == false PartTrackerTests.cpp:: PASSED: REQUIRE( s1b.isComplete() ) with expansion: true PartTrackerTests.cpp:: PASSED: REQUIRE( g1b.isComplete() ) with expansion: true PartTrackerTests.cpp:: PASSED: REQUIRE( testCase2.isComplete() ) with expansion: true ------------------------------------------------------------------------------- Tracker ------------------------------------------------------------------------------- PartTrackerTests.cpp: ............................................................................... PartTrackerTests.cpp:: PASSED: REQUIRE( testCase.isOpen() ) with expansion: true PartTrackerTests.cpp:: PASSED: REQUIRE( s1.isOpen() ) with expansion: true ------------------------------------------------------------------------------- Tracker start a generator ------------------------------------------------------------------------------- PartTrackerTests.cpp: ............................................................................... PartTrackerTests.cpp:: PASSED: REQUIRE( g1.isOpen() ) with expansion: true PartTrackerTests.cpp:: PASSED: REQUIRE( g1.index() == 0 ) with expansion: 0 == 0 PartTrackerTests.cpp:: PASSED: REQUIRE( g1.isComplete() == false ) with expansion: false == false PartTrackerTests.cpp:: PASSED: REQUIRE( s1.isComplete() == false ) with expansion: false == false ------------------------------------------------------------------------------- Tracker start a generator Start a new inner section ------------------------------------------------------------------------------- PartTrackerTests.cpp: ............................................................................... PartTrackerTests.cpp:: PASSED: REQUIRE( s2.isOpen() ) with expansion: true PartTrackerTests.cpp:: PASSED: REQUIRE( s2.isComplete() ) with expansion: true PartTrackerTests.cpp:: PASSED: REQUIRE( s1.isComplete() == false ) with expansion: false == false PartTrackerTests.cpp:: PASSED: REQUIRE( testCase.isComplete() == false ) with expansion: false == false ------------------------------------------------------------------------------- Tracker start a generator Start a new inner section Re-enter for second generation ------------------------------------------------------------------------------- PartTrackerTests.cpp: ............................................................................... PartTrackerTests.cpp:: PASSED: REQUIRE( testCase2.isOpen() ) with expansion: true PartTrackerTests.cpp:: PASSED: REQUIRE( s1b.isOpen() ) with expansion: true PartTrackerTests.cpp:: PASSED: REQUIRE( g1b.isOpen() ) with expansion: true PartTrackerTests.cpp:: PASSED: REQUIRE( g1b.index() == 1 ) with expansion: 1 == 1 PartTrackerTests.cpp:: PASSED: REQUIRE( s2b.isOpen() ) with expansion: true PartTrackerTests.cpp:: PASSED: REQUIRE( s2b.isComplete() ) with expansion: true PartTrackerTests.cpp:: PASSED: REQUIRE( g1b.isComplete() ) with expansion: true PartTrackerTests.cpp:: PASSED: REQUIRE( s1b.isComplete() ) with expansion: true PartTrackerTests.cpp:: PASSED: REQUIRE( testCase2.isComplete() ) with expansion: true ------------------------------------------------------------------------------- Tracker ------------------------------------------------------------------------------- PartTrackerTests.cpp: ............................................................................... PartTrackerTests.cpp:: PASSED: REQUIRE( testCase.isOpen() ) with expansion: true PartTrackerTests.cpp:: PASSED: REQUIRE( s1.isOpen() ) with expansion: true ------------------------------------------------------------------------------- Tracker start a generator ------------------------------------------------------------------------------- PartTrackerTests.cpp: ............................................................................... PartTrackerTests.cpp:: PASSED: REQUIRE( g1.isOpen() ) with expansion: true PartTrackerTests.cpp:: PASSED: REQUIRE( g1.index() == 0 ) with expansion: 0 == 0 PartTrackerTests.cpp:: PASSED: REQUIRE( g1.isComplete() == false ) with expansion: false == false PartTrackerTests.cpp:: PASSED: REQUIRE( s1.isComplete() == false ) with expansion: false == false ------------------------------------------------------------------------------- Tracker start a generator Fail an inner section ------------------------------------------------------------------------------- PartTrackerTests.cpp: ............................................................................... PartTrackerTests.cpp:: PASSED: REQUIRE( s2.isOpen() ) with expansion: true PartTrackerTests.cpp:: PASSED: REQUIRE( s2.isComplete() ) with expansion: true PartTrackerTests.cpp:: PASSED: REQUIRE( s2.isSuccessfullyCompleted() == false ) with expansion: false == false PartTrackerTests.cpp:: PASSED: REQUIRE( s1.isComplete() == false ) with expansion: false == false PartTrackerTests.cpp:: PASSED: REQUIRE( testCase.isComplete() == false ) with expansion: false == false ------------------------------------------------------------------------------- Tracker start a generator Fail an inner section Re-enter for second generation ------------------------------------------------------------------------------- PartTrackerTests.cpp: ............................................................................... PartTrackerTests.cpp:: PASSED: REQUIRE( testCase2.isOpen() ) with expansion: true PartTrackerTests.cpp:: PASSED: REQUIRE( s1b.isOpen() ) with expansion: true PartTrackerTests.cpp:: PASSED: REQUIRE( g1b.isOpen() ) with expansion: true PartTrackerTests.cpp:: PASSED: REQUIRE( g1b.index() == 0 ) with expansion: 0 == 0 PartTrackerTests.cpp:: PASSED: REQUIRE( s2b.isOpen() == false ) with expansion: false == false PartTrackerTests.cpp:: PASSED: REQUIRE( g1b.isComplete() == false ) with expansion: false == false PartTrackerTests.cpp:: PASSED: REQUIRE( s1b.isComplete() == false ) with expansion: false == false PartTrackerTests.cpp:: PASSED: REQUIRE( testCase2.isComplete() == false ) with expansion: false == false PartTrackerTests.cpp:: PASSED: REQUIRE( testCase3.isOpen() ) with expansion: true PartTrackerTests.cpp:: PASSED: REQUIRE( s1c.isOpen() ) with expansion: true PartTrackerTests.cpp:: PASSED: REQUIRE( g1c.isOpen() ) with expansion: true PartTrackerTests.cpp:: PASSED: REQUIRE( g1c.index() == 1 ) with expansion: 1 == 1 PartTrackerTests.cpp:: PASSED: REQUIRE( s2c.isOpen() ) with expansion: true PartTrackerTests.cpp:: PASSED: REQUIRE( s2c.isComplete() ) with expansion: true PartTrackerTests.cpp:: PASSED: REQUIRE( g1c.isComplete() ) with expansion: true PartTrackerTests.cpp:: PASSED: REQUIRE( s1c.isComplete() ) with expansion: true PartTrackerTests.cpp:: PASSED: REQUIRE( testCase3.isComplete() ) with expansion: true ------------------------------------------------------------------------------- Unexpected exceptions can be translated ------------------------------------------------------------------------------- ExceptionTests.cpp: ............................................................................... ExceptionTests.cpp:: FAILED: due to unexpected exception with message: 3.14 ------------------------------------------------------------------------------- Use a custom approx ------------------------------------------------------------------------------- ApproxTests.cpp: ............................................................................... ApproxTests.cpp:: PASSED: REQUIRE( d == approx( 1.23 ) ) with expansion: 1.23 == Approx( 1.23 ) ApproxTests.cpp:: PASSED: REQUIRE( d == approx( 1.22 ) ) with expansion: 1.23 == Approx( 1.22 ) ApproxTests.cpp:: PASSED: REQUIRE( d == approx( 1.24 ) ) with expansion: 1.23 == Approx( 1.24 ) ApproxTests.cpp:: PASSED: REQUIRE( d != approx( 1.25 ) ) with expansion: 1.23 != Approx( 1.25 ) ApproxTests.cpp:: PASSED: REQUIRE( approx( d ) == 1.23 ) with expansion: Approx( 1.23 ) == 1.23 ApproxTests.cpp:: PASSED: REQUIRE( approx( d ) == 1.22 ) with expansion: Approx( 1.23 ) == 1.22 ApproxTests.cpp:: PASSED: REQUIRE( approx( d ) == 1.24 ) with expansion: Approx( 1.23 ) == 1.24 ApproxTests.cpp:: PASSED: REQUIRE( approx( d ) != 1.25 ) with expansion: Approx( 1.23 ) != 1.25 ------------------------------------------------------------------------------- Variadic macros Section with one argument ------------------------------------------------------------------------------- VariadicMacrosTests.cpp: ............................................................................... VariadicMacrosTests.cpp:: PASSED: with message: no assertions ------------------------------------------------------------------------------- Vector matchers Contains (element) ------------------------------------------------------------------------------- MatchersTests.cpp: ............................................................................... MatchersTests.cpp:: PASSED: CHECK_THAT( v, VectorContains( 1 ) ) with expansion: { 1, 2, 3 } Contains: 1 MatchersTests.cpp:: PASSED: CHECK_THAT( v, VectorContains( 2 ) ) with expansion: { 1, 2, 3 } Contains: 2 ------------------------------------------------------------------------------- Vector matchers Contains (vector) ------------------------------------------------------------------------------- MatchersTests.cpp: ............................................................................... MatchersTests.cpp:: PASSED: CHECK_THAT( v, Contains( v2 ) ) with expansion: { 1, 2, 3 } Contains: { 1, 2 } MatchersTests.cpp:: PASSED: CHECK_THAT( v, Contains( v2 ) ) with expansion: { 1, 2, 3 } Contains: { 1, 2, 3 } MatchersTests.cpp:: PASSED: CHECK_THAT( v, Contains( empty) ) with expansion: { 1, 2, 3 } Contains: { } MatchersTests.cpp:: PASSED: CHECK_THAT( empty, Contains( empty) ) with expansion: { } Contains: { } ------------------------------------------------------------------------------- Vector matchers Equals ------------------------------------------------------------------------------- MatchersTests.cpp: ............................................................................... MatchersTests.cpp:: PASSED: CHECK_THAT( v, Equals( v ) ) with expansion: { 1, 2, 3 } Equals: { 1, 2, 3 } MatchersTests.cpp:: PASSED: CHECK_THAT( empty, Equals( empty ) ) with expansion: { } Equals: { } MatchersTests.cpp:: PASSED: CHECK_THAT( v, Equals( v2 ) ) with expansion: { 1, 2, 3 } Equals: { 1, 2, 3 } ------------------------------------------------------------------------------- Vector matchers that fail Contains (element) ------------------------------------------------------------------------------- MatchersTests.cpp: ............................................................................... MatchersTests.cpp:: FAILED: CHECK_THAT( v, VectorContains( -1 ) ) with expansion: { 1, 2, 3 } Contains: -1 MatchersTests.cpp:: FAILED: CHECK_THAT( empty, VectorContains( 1 ) ) with expansion: { } Contains: 1 ------------------------------------------------------------------------------- Vector matchers that fail Contains (vector) ------------------------------------------------------------------------------- MatchersTests.cpp: ............................................................................... MatchersTests.cpp:: FAILED: CHECK_THAT( empty, Contains( v) ) with expansion: { } Contains: { 1, 2, 3 } MatchersTests.cpp:: FAILED: CHECK_THAT( v, Contains( v2 ) ) with expansion: { 1, 2, 3 } Contains: { 1, 2, 4 } ------------------------------------------------------------------------------- Vector matchers that fail Equals ------------------------------------------------------------------------------- MatchersTests.cpp: ............................................................................... MatchersTests.cpp:: FAILED: CHECK_THAT( v, Equals( v2 ) ) with expansion: { 1, 2, 3 } Equals: { 1, 2 } MatchersTests.cpp:: FAILED: CHECK_THAT( v2, Equals( v ) ) with expansion: { 1, 2 } Equals: { 1, 2, 3 } MatchersTests.cpp:: FAILED: CHECK_THAT( empty, Equals( v ) ) with expansion: { } Equals: { 1, 2, 3 } MatchersTests.cpp:: FAILED: CHECK_THAT( v, Equals( empty ) ) with expansion: { 1, 2, 3 } Equals: { } ------------------------------------------------------------------------------- When checked exceptions are thrown they can be expected or unexpected ------------------------------------------------------------------------------- ExceptionTests.cpp: ............................................................................... ExceptionTests.cpp:: PASSED: REQUIRE_THROWS_AS( thisThrows(), std::domain_error ) ExceptionTests.cpp:: PASSED: REQUIRE_NOTHROW( thisDoesntThrow() ) ExceptionTests.cpp:: PASSED: REQUIRE_THROWS( thisThrows() ) ------------------------------------------------------------------------------- When unchecked exceptions are thrown directly they are always failures ------------------------------------------------------------------------------- ExceptionTests.cpp: ............................................................................... ExceptionTests.cpp:: FAILED: due to unexpected exception with message: unexpected exception ------------------------------------------------------------------------------- When unchecked exceptions are thrown during a CHECK the test should continue ------------------------------------------------------------------------------- ExceptionTests.cpp: ............................................................................... ExceptionTests.cpp:: FAILED: CHECK( thisThrows() == 0 ) due to unexpected exception with message: expected exception ------------------------------------------------------------------------------- When unchecked exceptions are thrown during a REQUIRE the test should abort fail ------------------------------------------------------------------------------- ExceptionTests.cpp: ............................................................................... ExceptionTests.cpp:: FAILED: REQUIRE( thisThrows() == 0 ) due to unexpected exception with message: expected exception ------------------------------------------------------------------------------- When unchecked exceptions are thrown from functions they are always failures ------------------------------------------------------------------------------- ExceptionTests.cpp: ............................................................................... ExceptionTests.cpp:: FAILED: CHECK( thisThrows() == 0 ) due to unexpected exception with message: expected exception ------------------------------------------------------------------------------- When unchecked exceptions are thrown from sections they are always failures section name ------------------------------------------------------------------------------- ExceptionTests.cpp: ............................................................................... ExceptionTests.cpp:: FAILED: due to unexpected exception with message: unexpected exception ------------------------------------------------------------------------------- Where the LHS is not a simple value ------------------------------------------------------------------------------- TrickyTests.cpp: ............................................................................... TrickyTests.cpp:: warning: Uncomment the code in this test to check that it gives a sensible compiler error ------------------------------------------------------------------------------- Where there is more to the expression after the RHS ------------------------------------------------------------------------------- TrickyTests.cpp: ............................................................................... TrickyTests.cpp:: warning: Uncomment the code in this test to check that it gives a sensible compiler error ------------------------------------------------------------------------------- X/level/0/a ------------------------------------------------------------------------------- TrickyTests.cpp: ............................................................................... TrickyTests.cpp:: PASSED: ------------------------------------------------------------------------------- X/level/0/b ------------------------------------------------------------------------------- TrickyTests.cpp: ............................................................................... TrickyTests.cpp:: PASSED: ------------------------------------------------------------------------------- X/level/1/a ------------------------------------------------------------------------------- TrickyTests.cpp: ............................................................................... TrickyTests.cpp:: PASSED: ------------------------------------------------------------------------------- X/level/1/b ------------------------------------------------------------------------------- TrickyTests.cpp: ............................................................................... TrickyTests.cpp:: PASSED: ------------------------------------------------------------------------------- XmlEncode normal string ------------------------------------------------------------------------------- MiscTests.cpp: ............................................................................... MiscTests.cpp:: PASSED: REQUIRE( encode( "normal string" ) == "normal string" ) with expansion: "normal string" == "normal string" ------------------------------------------------------------------------------- XmlEncode empty string ------------------------------------------------------------------------------- MiscTests.cpp: ............................................................................... MiscTests.cpp:: PASSED: REQUIRE( encode( "" ) == "" ) with expansion: "" == "" ------------------------------------------------------------------------------- XmlEncode string with ampersand ------------------------------------------------------------------------------- MiscTests.cpp: ............................................................................... MiscTests.cpp:: PASSED: REQUIRE( encode( "smith & jones" ) == "smith & jones" ) with expansion: "smith & jones" == "smith & jones" ------------------------------------------------------------------------------- XmlEncode string with less-than ------------------------------------------------------------------------------- MiscTests.cpp: ............................................................................... MiscTests.cpp:: PASSED: REQUIRE( encode( "smith < jones" ) == "smith < jones" ) with expansion: "smith < jones" == "smith < jones" ------------------------------------------------------------------------------- XmlEncode string with greater-than ------------------------------------------------------------------------------- MiscTests.cpp: ............................................................................... MiscTests.cpp:: PASSED: REQUIRE( encode( "smith > jones" ) == "smith > jones" ) with expansion: "smith > jones" == "smith > jones" MiscTests.cpp:: PASSED: REQUIRE( encode( "smith ]]> jones" ) == "smith ]]> jones" ) with expansion: "smith ]]> jones" == "smith ]]> jones" ------------------------------------------------------------------------------- XmlEncode string with quotes ------------------------------------------------------------------------------- MiscTests.cpp: ............................................................................... MiscTests.cpp:: PASSED: REQUIRE( encode( stringWithQuotes ) == stringWithQuotes ) with expansion: "don't "quote" me on that" == "don't "quote" me on that" MiscTests.cpp:: PASSED: REQUIRE( encode( stringWithQuotes, Catch::XmlEncode::ForAttributes ) == "don't "quote" me on that" ) with expansion: "don't "quote" me on that" == "don't "quote" me on that" ------------------------------------------------------------------------------- XmlEncode string with control char (1) ------------------------------------------------------------------------------- MiscTests.cpp: ............................................................................... MiscTests.cpp:: PASSED: REQUIRE( encode( "[\x01]" ) == "[\\x01]" ) with expansion: "[\x01]" == "[\x01]" ------------------------------------------------------------------------------- XmlEncode string with control char (x7F) ------------------------------------------------------------------------------- MiscTests.cpp: ............................................................................... MiscTests.cpp:: PASSED: REQUIRE( encode( "[\x7F]" ) == "[\\x7F]" ) with expansion: "[\x7F]" == "[\x7F]" ------------------------------------------------------------------------------- atomic if ------------------------------------------------------------------------------- MiscTests.cpp: ............................................................................... MiscTests.cpp:: PASSED: REQUIRE( x == 0 ) with expansion: 0 == 0 ------------------------------------------------------------------------------- boolean member ------------------------------------------------------------------------------- TrickyTests.cpp: ............................................................................... TrickyTests.cpp:: PASSED: REQUIRE( obj.prop != 0 ) with expansion: 0x != 0 ------------------------------------------------------------------------------- checkedElse ------------------------------------------------------------------------------- MiscTests.cpp: ............................................................................... MiscTests.cpp:: PASSED: CHECKED_ELSE( flag ) with expansion: true MiscTests.cpp:: PASSED: REQUIRE( testCheckedElse( true ) ) with expansion: true ------------------------------------------------------------------------------- checkedElse, failing ------------------------------------------------------------------------------- MiscTests.cpp: ............................................................................... MiscTests.cpp:: FAILED: CHECKED_ELSE( flag ) with expansion: false MiscTests.cpp:: FAILED: REQUIRE( testCheckedElse( false ) ) with expansion: false ------------------------------------------------------------------------------- checkedIf ------------------------------------------------------------------------------- MiscTests.cpp: ............................................................................... MiscTests.cpp:: PASSED: CHECKED_IF( flag ) with expansion: true MiscTests.cpp:: PASSED: REQUIRE( testCheckedIf( true ) ) with expansion: true ------------------------------------------------------------------------------- checkedIf, failing ------------------------------------------------------------------------------- MiscTests.cpp: ............................................................................... MiscTests.cpp:: FAILED: CHECKED_IF( flag ) with expansion: false MiscTests.cpp:: FAILED: REQUIRE( testCheckedIf( false ) ) with expansion: false ------------------------------------------------------------------------------- comparisons between const int variables ------------------------------------------------------------------------------- ConditionTests.cpp: ............................................................................... ConditionTests.cpp:: PASSED: REQUIRE( unsigned_char_var == 1 ) with expansion: 1 == 1 ConditionTests.cpp:: PASSED: REQUIRE( unsigned_short_var == 1 ) with expansion: 1 == 1 ConditionTests.cpp:: PASSED: REQUIRE( unsigned_int_var == 1 ) with expansion: 1 == 1 ConditionTests.cpp:: PASSED: REQUIRE( unsigned_long_var == 1 ) with expansion: 1 == 1 ------------------------------------------------------------------------------- comparisons between int variables ------------------------------------------------------------------------------- ConditionTests.cpp: ............................................................................... ConditionTests.cpp:: PASSED: REQUIRE( long_var == unsigned_char_var ) with expansion: 1 == 1 ConditionTests.cpp:: PASSED: REQUIRE( long_var == unsigned_short_var ) with expansion: 1 == 1 ConditionTests.cpp:: PASSED: REQUIRE( long_var == unsigned_int_var ) with expansion: 1 == 1 ConditionTests.cpp:: PASSED: REQUIRE( long_var == unsigned_long_var ) with expansion: 1 == 1 ------------------------------------------------------------------------------- even more nested SECTION tests c d (leaf) ------------------------------------------------------------------------------- MiscTests.cpp: ............................................................................... MiscTests.cpp:: PASSED: ------------------------------------------------------------------------------- even more nested SECTION tests c e (leaf) ------------------------------------------------------------------------------- MiscTests.cpp: ............................................................................... MiscTests.cpp:: PASSED: ------------------------------------------------------------------------------- even more nested SECTION tests f (leaf) ------------------------------------------------------------------------------- MiscTests.cpp: ............................................................................... MiscTests.cpp:: PASSED: spanner------------------------------------------------------------------------------- just failure ------------------------------------------------------------------------------- MessageTests.cpp: ............................................................................... MessageTests.cpp:: FAILED: explicitly with message: Previous info should not be seen ------------------------------------------------------------------------------- looped SECTION tests s1 ------------------------------------------------------------------------------- MiscTests.cpp: ............................................................................... MiscTests.cpp:: FAILED: CHECK( b > a ) with expansion: 0 > 1 ------------------------------------------------------------------------------- looped tests ------------------------------------------------------------------------------- MiscTests.cpp: ............................................................................... MiscTests.cpp:: FAILED: CHECK( ( fib[i] % 2 ) == 0 ) with expansion: 1 == 0 with message: Testing if fib[0] (1) is even MiscTests.cpp:: FAILED: CHECK( ( fib[i] % 2 ) == 0 ) with expansion: 1 == 0 with message: Testing if fib[1] (1) is even MiscTests.cpp:: PASSED: CHECK( ( fib[i] % 2 ) == 0 ) with expansion: 0 == 0 with message: Testing if fib[2] (2) is even MiscTests.cpp:: FAILED: CHECK( ( fib[i] % 2 ) == 0 ) with expansion: 1 == 0 with message: Testing if fib[3] (3) is even MiscTests.cpp:: FAILED: CHECK( ( fib[i] % 2 ) == 0 ) with expansion: 1 == 0 with message: Testing if fib[4] (5) is even MiscTests.cpp:: PASSED: CHECK( ( fib[i] % 2 ) == 0 ) with expansion: 0 == 0 with message: Testing if fib[5] (8) is even MiscTests.cpp:: FAILED: CHECK( ( fib[i] % 2 ) == 0 ) with expansion: 1 == 0 with message: Testing if fib[6] (13) is even MiscTests.cpp:: FAILED: CHECK( ( fib[i] % 2 ) == 0 ) with expansion: 1 == 0 with message: Testing if fib[7] (21) is even ------------------------------------------------------------------------------- more nested SECTION tests s1 s2 ------------------------------------------------------------------------------- MiscTests.cpp: ............................................................................... MiscTests.cpp:: FAILED: REQUIRE( a == b ) with expansion: 1 == 2 ------------------------------------------------------------------------------- more nested SECTION tests s1 s3 ------------------------------------------------------------------------------- MiscTests.cpp: ............................................................................... MiscTests.cpp:: PASSED: REQUIRE( a != b ) with expansion: 1 != 2 ------------------------------------------------------------------------------- more nested SECTION tests s1 s4 ------------------------------------------------------------------------------- MiscTests.cpp: ............................................................................... MiscTests.cpp:: PASSED: REQUIRE( a < b ) with expansion: 1 < 2 ------------------------------------------------------------------------------- nested SECTION tests s1 ------------------------------------------------------------------------------- MiscTests.cpp: ............................................................................... MiscTests.cpp:: PASSED: REQUIRE( a != b ) with expansion: 1 != 2 MiscTests.cpp:: PASSED: REQUIRE( b != a ) with expansion: 2 != 1 ------------------------------------------------------------------------------- nested SECTION tests s1 s2 ------------------------------------------------------------------------------- MiscTests.cpp: ............................................................................... MiscTests.cpp:: PASSED: REQUIRE( a != b ) with expansion: 1 != 2 ------------------------------------------------------------------------------- non streamable - with conv. op ------------------------------------------------------------------------------- TrickyTests.cpp: ............................................................................... TrickyTests.cpp:: PASSED: REQUIRE( s == "7" ) with expansion: "7" == "7" ------------------------------------------------------------------------------- not allowed ------------------------------------------------------------------------------- MiscTests.cpp: ............................................................................... MiscTests.cpp:: PASSED: ------------------------------------------------------------------------------- null strings ------------------------------------------------------------------------------- MiscTests.cpp: ............................................................................... MiscTests.cpp:: PASSED: REQUIRE( makeString( false ) != static_cast(0) ) with expansion: "valid string" != {null string} MiscTests.cpp:: PASSED: REQUIRE( makeString( true ) == static_cast(0) ) with expansion: {null string} == {null string} ------------------------------------------------------------------------------- pair > -> toString ------------------------------------------------------------------------------- ToStringPair.cpp: ............................................................................... ToStringPair.cpp:: PASSED: REQUIRE( Catch::toString( pair ) == "{ { 42, \"Arthur\" }, { \"Ford\", 24 } }" ) with expansion: "{ { 42, "Arthur" }, { "Ford", 24 } }" == "{ { 42, "Arthur" }, { "Ford", 24 } }" ------------------------------------------------------------------------------- pointer to class ------------------------------------------------------------------------------- TrickyTests.cpp: ............................................................................... TrickyTests.cpp:: PASSED: REQUIRE( p == 0 ) with expansion: NULL == 0 ------------------------------------------------------------------------------- random SECTION tests s1 ------------------------------------------------------------------------------- MiscTests.cpp: ............................................................................... MiscTests.cpp:: PASSED: REQUIRE( a != b ) with expansion: 1 != 2 MiscTests.cpp:: PASSED: REQUIRE( b != a ) with expansion: 2 != 1 ------------------------------------------------------------------------------- random SECTION tests s2 ------------------------------------------------------------------------------- MiscTests.cpp: ............................................................................... MiscTests.cpp:: PASSED: REQUIRE( a != b ) with expansion: 1 != 2 ------------------------------------------------------------------------------- replaceInPlace replace single char ------------------------------------------------------------------------------- TestMain.cpp: ............................................................................... TestMain.cpp:: PASSED: CHECK( replaceInPlace( letters, "b", "z" ) ) with expansion: true TestMain.cpp:: PASSED: CHECK( letters == "azcdefcg" ) with expansion: "azcdefcg" == "azcdefcg" ------------------------------------------------------------------------------- replaceInPlace replace two chars ------------------------------------------------------------------------------- TestMain.cpp: ............................................................................... TestMain.cpp:: PASSED: CHECK( replaceInPlace( letters, "c", "z" ) ) with expansion: true TestMain.cpp:: PASSED: CHECK( letters == "abzdefzg" ) with expansion: "abzdefzg" == "abzdefzg" ------------------------------------------------------------------------------- replaceInPlace replace first char ------------------------------------------------------------------------------- TestMain.cpp: ............................................................................... TestMain.cpp:: PASSED: CHECK( replaceInPlace( letters, "a", "z" ) ) with expansion: true TestMain.cpp:: PASSED: CHECK( letters == "zbcdefcg" ) with expansion: "zbcdefcg" == "zbcdefcg" ------------------------------------------------------------------------------- replaceInPlace replace last char ------------------------------------------------------------------------------- TestMain.cpp: ............................................................................... TestMain.cpp:: PASSED: CHECK( replaceInPlace( letters, "g", "z" ) ) with expansion: true TestMain.cpp:: PASSED: CHECK( letters == "abcdefcz" ) with expansion: "abcdefcz" == "abcdefcz" ------------------------------------------------------------------------------- replaceInPlace replace all chars ------------------------------------------------------------------------------- TestMain.cpp: ............................................................................... TestMain.cpp:: PASSED: CHECK( replaceInPlace( letters, letters, "replaced" ) ) with expansion: true TestMain.cpp:: PASSED: CHECK( letters == "replaced" ) with expansion: "replaced" == "replaced" ------------------------------------------------------------------------------- replaceInPlace replace no chars ------------------------------------------------------------------------------- TestMain.cpp: ............................................................................... TestMain.cpp:: PASSED: CHECK_FALSE( replaceInPlace( letters, "x", "z" ) ) with expansion: !false TestMain.cpp:: PASSED: CHECK( letters == letters ) with expansion: "abcdefcg" == "abcdefcg" ------------------------------------------------------------------------------- replaceInPlace escape ' ------------------------------------------------------------------------------- TestMain.cpp: ............................................................................... TestMain.cpp:: PASSED: CHECK( replaceInPlace( s, "'", "|'" ) ) with expansion: true TestMain.cpp:: PASSED: CHECK( s == "didn|'t" ) with expansion: "didn|'t" == "didn|'t" ------------------------------------------------------------------------------- send a single char to INFO ------------------------------------------------------------------------------- MiscTests.cpp: ............................................................................... MiscTests.cpp:: FAILED: REQUIRE( false ) with message: 3 ------------------------------------------------------------------------------- sends information to INFO ------------------------------------------------------------------------------- MessageTests.cpp: ............................................................................... MessageTests.cpp:: FAILED: REQUIRE( false ) with messages: hi i := 7 ------------------------------------------------------------------------------- std::pair -> toString ------------------------------------------------------------------------------- ToStringPair.cpp: ............................................................................... ToStringPair.cpp:: PASSED: REQUIRE( Catch::toString(value) == "{ 34, \"xyzzy\" }" ) with expansion: "{ 34, "xyzzy" }" == "{ 34, "xyzzy" }" ------------------------------------------------------------------------------- std::pair -> toString ------------------------------------------------------------------------------- ToStringPair.cpp: ............................................................................... ToStringPair.cpp:: PASSED: REQUIRE( Catch::toString( value ) == "{ 34, \"xyzzy\" }" ) with expansion: "{ 34, "xyzzy" }" == "{ 34, "xyzzy" }" ------------------------------------------------------------------------------- std::vector > -> toString ------------------------------------------------------------------------------- ToStringPair.cpp: ............................................................................... ToStringPair.cpp:: PASSED: REQUIRE( Catch::toString( pr ) == "{ { \"green\", 55 } }" ) with expansion: "{ { "green", 55 } }" == "{ { "green", 55 } }" ------------------------------------------------------------------------------- string literals of different sizes can be compared ------------------------------------------------------------------------------- TrickyTests.cpp: ............................................................................... TrickyTests.cpp:: FAILED: REQUIRE( std::string( "first" ) == "second" ) with expansion: "first" == "second" ------------------------------------------------------------------------------- toString on const wchar_t const pointer returns the string contents ------------------------------------------------------------------------------- MiscTests.cpp: ............................................................................... MiscTests.cpp:: PASSED: CHECK( result == "\"wide load\"" ) with expansion: ""wide load"" == ""wide load"" ------------------------------------------------------------------------------- toString on const wchar_t pointer returns the string contents ------------------------------------------------------------------------------- MiscTests.cpp: ............................................................................... MiscTests.cpp:: PASSED: CHECK( result == "\"wide load\"" ) with expansion: ""wide load"" == ""wide load"" ------------------------------------------------------------------------------- toString on wchar_t const pointer returns the string contents ------------------------------------------------------------------------------- MiscTests.cpp: ............................................................................... MiscTests.cpp:: PASSED: CHECK( result == "\"wide load\"" ) with expansion: ""wide load"" == ""wide load"" ------------------------------------------------------------------------------- toString on wchar_t returns the string contents ------------------------------------------------------------------------------- MiscTests.cpp: ............................................................................... MiscTests.cpp:: PASSED: CHECK( result == "\"wide load\"" ) with expansion: ""wide load"" == ""wide load"" ------------------------------------------------------------------------------- toString( has_maker ) ------------------------------------------------------------------------------- ToStringWhich.cpp: ............................................................................... ToStringWhich.cpp:: PASSED: REQUIRE( Catch::toString( item ) == "StringMaker" ) with expansion: "StringMaker" == "StringMaker" ------------------------------------------------------------------------------- toString( has_maker_and_toString ) ------------------------------------------------------------------------------- ToStringWhich.cpp: ............................................................................... ToStringWhich.cpp:: PASSED: REQUIRE( Catch::toString( item ) == "toString( has_maker_and_toString )" ) with expansion: "toString( has_maker_and_toString )" == "toString( has_maker_and_toString )" ------------------------------------------------------------------------------- toString( has_toString ) ------------------------------------------------------------------------------- ToStringWhich.cpp: ............................................................................... ToStringWhich.cpp:: PASSED: REQUIRE( Catch::toString( item ) == "toString( has_toString )" ) with expansion: "toString( has_toString )" == "toString( has_toString )" ------------------------------------------------------------------------------- toString( vectors ............................................................................... ToStringWhich.cpp:: PASSED: REQUIRE( Catch::toString( v ) == "{ StringMaker }" ) with expansion: "{ StringMaker }" == "{ StringMaker }" ------------------------------------------------------------------------------- toString(enum w/operator<<) ------------------------------------------------------------------------------- EnumToString.cpp: ............................................................................... EnumToString.cpp:: PASSED: CHECK( Catch::toString(e0) == "E2{0}" ) with expansion: "E2{0}" == "E2{0}" EnumToString.cpp:: PASSED: CHECK( Catch::toString(e1) == "E2{1}" ) with expansion: "E2{1}" == "E2{1}" ------------------------------------------------------------------------------- toString(enum) ------------------------------------------------------------------------------- EnumToString.cpp: ............................................................................... EnumToString.cpp:: PASSED: CHECK( Catch::toString(e0) == "0" ) with expansion: "0" == "0" EnumToString.cpp:: PASSED: CHECK( Catch::toString(e1) == "1" ) with expansion: "1" == "1" ------------------------------------------------------------------------------- vector -> toString ------------------------------------------------------------------------------- ToStringVector.cpp: ............................................................................... ToStringVector.cpp:: PASSED: REQUIRE( Catch::toString(vv) == "{ }" ) with expansion: "{ }" == "{ }" ToStringVector.cpp:: PASSED: REQUIRE( Catch::toString(vv) == "{ 42 }" ) with expansion: "{ 42 }" == "{ 42 }" ToStringVector.cpp:: PASSED: REQUIRE( Catch::toString(vv) == "{ 42, 250 }" ) with expansion: "{ 42, 250 }" == "{ 42, 250 }" ------------------------------------------------------------------------------- vector -> toString ------------------------------------------------------------------------------- ToStringVector.cpp: ............................................................................... ToStringVector.cpp:: PASSED: REQUIRE( Catch::toString(vv) == "{ }" ) with expansion: "{ }" == "{ }" ToStringVector.cpp:: PASSED: REQUIRE( Catch::toString(vv) == "{ \"hello\" }" ) with expansion: "{ "hello" }" == "{ "hello" }" ToStringVector.cpp:: PASSED: REQUIRE( Catch::toString(vv) == "{ \"hello\", \"world\" }" ) with expansion: "{ "hello", "world" }" == "{ "hello", "world" }" ------------------------------------------------------------------------------- vectors can be sized and resized ------------------------------------------------------------------------------- MiscTests.cpp: ............................................................................... MiscTests.cpp:: PASSED: REQUIRE( v.size() == 5 ) with expansion: 5 == 5 MiscTests.cpp:: PASSED: REQUIRE( v.capacity() >= 5 ) with expansion: 5 >= 5 ------------------------------------------------------------------------------- vectors can be sized and resized resizing bigger changes size and capacity ------------------------------------------------------------------------------- MiscTests.cpp: ............................................................................... MiscTests.cpp:: PASSED: REQUIRE( v.size() == 10 ) with expansion: 10 == 10 MiscTests.cpp:: PASSED: REQUIRE( v.capacity() >= 10 ) with expansion: 10 >= 10 ------------------------------------------------------------------------------- vectors can be sized and resized ------------------------------------------------------------------------------- MiscTests.cpp: ............................................................................... MiscTests.cpp:: PASSED: REQUIRE( v.size() == 5 ) with expansion: 5 == 5 MiscTests.cpp:: PASSED: REQUIRE( v.capacity() >= 5 ) with expansion: 5 >= 5 ------------------------------------------------------------------------------- vectors can be sized and resized resizing smaller changes size but not capacity ------------------------------------------------------------------------------- MiscTests.cpp: ............................................................................... MiscTests.cpp:: PASSED: REQUIRE( v.size() == 0 ) with expansion: 0 == 0 MiscTests.cpp:: PASSED: REQUIRE( v.capacity() >= 5 ) with expansion: 5 >= 5 ------------------------------------------------------------------------------- vectors can be sized and resized resizing smaller changes size but not capacity We can use the 'swap trick' to reset the capacity ------------------------------------------------------------------------------- MiscTests.cpp: ............................................................................... MiscTests.cpp:: PASSED: REQUIRE( v.capacity() == 0 ) with expansion: 0 == 0 ------------------------------------------------------------------------------- vectors can be sized and resized ------------------------------------------------------------------------------- MiscTests.cpp: ............................................................................... MiscTests.cpp:: PASSED: REQUIRE( v.size() == 5 ) with expansion: 5 == 5 MiscTests.cpp:: PASSED: REQUIRE( v.capacity() >= 5 ) with expansion: 5 >= 5 ------------------------------------------------------------------------------- vectors can be sized and resized reserving bigger changes capacity but not size ------------------------------------------------------------------------------- MiscTests.cpp: ............................................................................... MiscTests.cpp:: PASSED: REQUIRE( v.size() == 5 ) with expansion: 5 == 5 MiscTests.cpp:: PASSED: REQUIRE( v.capacity() >= 10 ) with expansion: 10 >= 10 ------------------------------------------------------------------------------- vectors can be sized and resized ------------------------------------------------------------------------------- MiscTests.cpp: ............................................................................... MiscTests.cpp:: PASSED: REQUIRE( v.size() == 5 ) with expansion: 5 == 5 MiscTests.cpp:: PASSED: REQUIRE( v.capacity() >= 5 ) with expansion: 5 >= 5 ------------------------------------------------------------------------------- vectors can be sized and resized reserving smaller does not change size or capacity ------------------------------------------------------------------------------- MiscTests.cpp: ............................................................................... MiscTests.cpp:: PASSED: REQUIRE( v.size() == 5 ) with expansion: 5 == 5 MiscTests.cpp:: PASSED: REQUIRE( v.capacity() >= 5 ) with expansion: 5 >= 5 ------------------------------------------------------------------------------- xmlentitycheck embedded xml ------------------------------------------------------------------------------- MiscTests.cpp: ............................................................................... MiscTests.cpp:: PASSED: ------------------------------------------------------------------------------- xmlentitycheck encoded chars ------------------------------------------------------------------------------- MiscTests.cpp: ............................................................................... MiscTests.cpp:: PASSED: =============================================================================== test cases: 171 | 120 passed | 47 failed | 4 failed as expected assertions: 985 | 871 passed | 93 failed | 21 failed as expected catch-1.12.1/projects/SelfTest/Baselines/console.swa4.approved.txt000066400000000000000000000147651325474075300250730ustar00rootroot00000000000000 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ is a host application. Run with -? for options ------------------------------------------------------------------------------- # A test name that starts with a # ------------------------------------------------------------------------------- MiscTests.cpp: ............................................................................... MiscTests.cpp:: PASSED: with message: yay ------------------------------------------------------------------------------- #748 - captures with unexpected exceptions outside assertions ------------------------------------------------------------------------------- ExceptionTests.cpp: ............................................................................... ExceptionTests.cpp:: FAILED: due to unexpected exception with messages: answer := 42 expected exception ------------------------------------------------------------------------------- #748 - captures with unexpected exceptions inside REQUIRE_NOTHROW ------------------------------------------------------------------------------- ExceptionTests.cpp: ............................................................................... ExceptionTests.cpp:: FAILED: REQUIRE_NOTHROW( thisThrows() ) due to unexpected exception with messages: answer := 42 expected exception ------------------------------------------------------------------------------- #748 - captures with unexpected exceptions inside REQUIRE_THROWS ------------------------------------------------------------------------------- ExceptionTests.cpp: ............................................................................... ExceptionTests.cpp:: PASSED: REQUIRE_THROWS( thisThrows() ) with message: answer := 42 ------------------------------------------------------------------------------- #809 ------------------------------------------------------------------------------- CompilationTests.cpp: ............................................................................... CompilationTests.cpp:: PASSED: REQUIRE( 42 == f ) with expansion: 42 == {?} ------------------------------------------------------------------------------- #833 ------------------------------------------------------------------------------- CompilationTests.cpp: ............................................................................... CompilationTests.cpp:: PASSED: REQUIRE( a == t ) with expansion: 3 == 3 CompilationTests.cpp:: PASSED: CHECK( a == t ) with expansion: 3 == 3 CompilationTests.cpp:: PASSED: REQUIRE_THROWS( throws_int(true) ) CompilationTests.cpp:: PASSED: CHECK_THROWS_AS( throws_int(true), const int& ) CompilationTests.cpp:: PASSED: REQUIRE_NOTHROW( throws_int(false) ) CompilationTests.cpp:: PASSED: REQUIRE_THAT( "aaa", Catch::EndsWith("aaa") ) with expansion: "aaa" ends with: "aaa" CompilationTests.cpp:: PASSED: REQUIRE( templated_tests(3) ) with expansion: true ------------------------------------------------------------------------------- #835 -- errno should not be touched by Catch ------------------------------------------------------------------------------- MiscTests.cpp: ............................................................................... MiscTests.cpp:: FAILED: CHECK( f() == 0 ) with expansion: 1 == 0 MiscTests.cpp:: PASSED: REQUIRE( errno == 1 ) with expansion: 1 == 1 ------------------------------------------------------------------------------- #961 -- Dynamically created sections should all be reported Looped section 0 ------------------------------------------------------------------------------- MiscTests.cpp: ............................................................................... MiscTests.cpp:: PASSED: with message: Everything is OK ------------------------------------------------------------------------------- #961 -- Dynamically created sections should all be reported Looped section 1 ------------------------------------------------------------------------------- MiscTests.cpp: ............................................................................... MiscTests.cpp:: PASSED: with message: Everything is OK ------------------------------------------------------------------------------- #961 -- Dynamically created sections should all be reported Looped section 2 ------------------------------------------------------------------------------- MiscTests.cpp: ............................................................................... MiscTests.cpp:: PASSED: with message: Everything is OK ------------------------------------------------------------------------------- #961 -- Dynamically created sections should all be reported Looped section 3 ------------------------------------------------------------------------------- MiscTests.cpp: ............................................................................... MiscTests.cpp:: PASSED: with message: Everything is OK ------------------------------------------------------------------------------- #961 -- Dynamically created sections should all be reported Looped section 4 ------------------------------------------------------------------------------- MiscTests.cpp: ............................................................................... MiscTests.cpp:: PASSED: with message: Everything is OK ------------------------------------------------------------------------------- 'Not' checks that should fail ------------------------------------------------------------------------------- ConditionTests.cpp: ............................................................................... ConditionTests.cpp:: FAILED: CHECK( false != false ) ConditionTests.cpp:: FAILED: CHECK( true != true ) ConditionTests.cpp:: FAILED: CHECK( !true ) with expansion: false ConditionTests.cpp:: FAILED: CHECK_FALSE( true ) with expansion: !true =============================================================================== test cases: 7 | 4 passed | 1 failed | 2 failed as expected assertions: 23 | 16 passed | 4 failed | 3 failed as expected catch-1.12.1/projects/SelfTest/Baselines/junit.sw.approved.txt000066400000000000000000001337261325474075300243340ustar00rootroot00000000000000 expected exception answer := 42 ExceptionTests.cpp: expected exception answer := 42 ExceptionTests.cpp: MiscTests.cpp: ConditionTests.cpp: ConditionTests.cpp: ConditionTests.cpp: ConditionTests.cpp: ConditionTests.cpp: ConditionTests.cpp: ConditionTests.cpp: ConditionTests.cpp: ClassTests.cpp: ClassTests.cpp: to infinity and beyond MiscTests.cpp: TrickyTests.cpp: TrickyTests.cpp: unexpected exception ExceptionTests.cpp: MatchersTests.cpp: custom exception - not std ExceptionTests.cpp: custom exception - not std ExceptionTests.cpp: custom std exception ExceptionTests.cpp: MatchersTests.cpp: ConditionTests.cpp: ConditionTests.cpp: ConditionTests.cpp: ConditionTests.cpp: ConditionTests.cpp: ConditionTests.cpp: ConditionTests.cpp: ConditionTests.cpp: ConditionTests.cpp: ConditionTests.cpp: ConditionTests.cpp: ConditionTests.cpp: ConditionTests.cpp: MatchersTests.cpp: expected exception ExceptionTests.cpp: ExceptionTests.cpp: expected exception ExceptionTests.cpp: This is a failure MessageTests.cpp: MessageTests.cpp: This is a failure MessageTests.cpp: this message should be logged so should this MessageTests.cpp: this message may be logged later this message should be logged MessageTests.cpp: this message may be logged later this message should be logged and this, but later MessageTests.cpp: ConditionTests.cpp: ConditionTests.cpp: ConditionTests.cpp: ConditionTests.cpp: ConditionTests.cpp: MatchersTests.cpp: MatchersTests.cpp: ExceptionTests.cpp: custom exception ExceptionTests.cpp: ConditionTests.cpp: ConditionTests.cpp: ConditionTests.cpp: ConditionTests.cpp: ConditionTests.cpp: ConditionTests.cpp: ConditionTests.cpp: ConditionTests.cpp: ConditionTests.cpp: ConditionTests.cpp: ConditionTests.cpp: ConditionTests.cpp: ConditionTests.cpp: ConditionTests.cpp: ConditionTests.cpp: ConditionTests.cpp: ConditionTests.cpp: ConditionTests.cpp: ConditionTests.cpp: Message from section one MessageTests.cpp: Message from section two MessageTests.cpp: DecompositionTests.cpp: current counter 10 i := 10 MessageTests.cpp: A string sent directly to stdout A string sent directly to stderr Write to std::cerr Write to std::clog Interleaved writes to error streams Message from section one Message from section two MatchersTests.cpp: hello hello MiscTests.cpp: 3.14 ExceptionTests.cpp: MatchersTests.cpp: MatchersTests.cpp: MatchersTests.cpp: MatchersTests.cpp: MatchersTests.cpp: MatchersTests.cpp: MatchersTests.cpp: MatchersTests.cpp: unexpected exception ExceptionTests.cpp: expected exception ExceptionTests.cpp: expected exception ExceptionTests.cpp: expected exception ExceptionTests.cpp: unexpected exception ExceptionTests.cpp: MiscTests.cpp: MiscTests.cpp: MiscTests.cpp: MiscTests.cpp: Previous info should not be seen MessageTests.cpp: MiscTests.cpp: Testing if fib[0] (1) is even MiscTests.cpp: Testing if fib[1] (1) is even MiscTests.cpp: Testing if fib[3] (3) is even MiscTests.cpp: Testing if fib[4] (5) is even MiscTests.cpp: Testing if fib[6] (13) is even MiscTests.cpp: Testing if fib[7] (21) is even MiscTests.cpp: MiscTests.cpp: 3 MiscTests.cpp: hi i := 7 MessageTests.cpp: TrickyTests.cpp: A string sent directly to stdout Message from section one Message from section two hello hello A string sent directly to stderr Write to std::cerr Write to std::clog Interleaved writes to error streams catch-1.12.1/projects/SelfTest/Baselines/xml.sw.approved.txt000066400000000000000000014220371325474075300240000ustar00rootroot00000000000000
answer := 42 expected exception
answer := 42 thisThrows() thisThrows() expected exception
answer := 42 thisThrows() thisThrows()
42 == f 42 == {?} a == t 3 == 3 a == t 3 == 3 throws_int(true) throws_int(true) throws_int(true), const int& throws_int(true), const int& throws_int(false) throws_int(false) "aaa", Catch::EndsWith("aaa") "aaa" ends with: "aaa" templated_tests<int>(3) true f() == 0 1 == 0 errno == 1 1 == 1
false != false false != false true != true true != true !true false !(true) !true !trueValue false !(trueValue) !true !(1 == 1) false !(1 == 1) !(1 == 1) false == false false == false true == true true == true !false true !(false) !false !falseValue true !(falseValue) !false !(1 == 2) true !(1 == 2) !(1 == 2)
is_true<true>::value == true true == true true == is_true<true>::value true == true
is_true<false>::value == false false == false false == is_true<false>::value false == false
!is_true<false>::value true
!!is_true<true>::value true
is_true<true>::value true !(is_true<false>::value) !false
s == "world" "hello" == "world" s == "hello" "hello" == "hello" m_a == 2 1 == 2 m_a == 1 1 == 1
to infinity and beyond
&o1 == &o2 0x == 0x o1 == o2 {?} == {?} 104.0 != Approx(100.0) 104.0 != Approx( 100.0 ) 104.0 == Approx(100.0).margin(5) 104.0 == Approx( 100.0 ) 104.0 == Approx(100.0).margin(4) 104.0 == Approx( 100.0 ) 104.0 != Approx(100.0).margin(3) 104.0 != Approx( 100.0 ) 100.3 != Approx(100.0) 100.3 != Approx( 100.0 ) 100.3 == Approx(100.0).margin(0.5) 100.3 == Approx( 100.0 ) testStringForMatching(), AllOf( Catch::Contains( "string" ), Catch::Contains( "abc" ) ) "this string contains 'abc' as a substring" ( contains: "string" and contains: "abc" ) i++ == 7 7 == 7 i++ == 8 8 == 8 1 == 1 1 == 1 {Unknown expression after the reported line} {Unknown expression after the reported line} unexpected exception testStringForMatching(), AnyOf( Catch::Contains( "string" ), Catch::Contains( "not there" ) ) "this string contains 'abc' as a substring" ( contains: "string" or contains: "not there" ) testStringForMatching(), AnyOf( Catch::Contains( "not there" ), Catch::Contains( "string" ) ) "this string contains 'abc' as a substring" ( contains: "not there" or contains: "string" ) 0.25f == Approx(0.0f).margin(0.25f) 0.25f == Approx( 0.0 ) 0.0f == Approx(0.25f).margin(0.25f) 0.0f == Approx( 0.25 ) 0.5f == Approx(0.25f).margin(0.25f) 0.5f == Approx( 0.25 ) 245.0f == Approx(245.25f).margin(0.25f) 245.0f == Approx( 245.25 ) 245.5f == Approx(245.25f).margin(0.25f) 245.5f == Approx( 245.25 ) divide( 22, 7 ) == Approx( 3.141 ).epsilon( 0.001 ) 3.1428571429 == Approx( 3.141 ) divide( 22, 7 ) != Approx( 3.141 ).epsilon( 0.0001 ) 3.1428571429 != Approx( 3.141 ) d != Approx( 1.231 ) 1.23 != Approx( 1.231 ) d == Approx( 1.231 ).epsilon( 0.1 ) 1.23 == Approx( 1.231 ) 1.23f == Approx( 1.23f ) 1.23f == Approx( 1.2300000191 ) 0.0f == Approx( 0.0f ) 0.0f == Approx( 0.0 ) 1 == Approx( 1 ) 1 == Approx( 1.0 ) 0 == Approx( 0 ) 0 == Approx( 0.0 ) 1.0f == Approx( 1 ) 1.0f == Approx( 1.0 ) 0 == Approx( dZero) 0 == Approx( 0.0 ) 0 == Approx( dSmall ).epsilon( 0.001 ) 0 == Approx( 0.00001 ) 1.234f == Approx( dMedium ) 1.234f == Approx( 1.234 ) dMedium == Approx( 1.234f ) 1.234 == Approx( 1.2339999676 ) Catch::alwaysTrue() true
Catch::alwaysTrue() true
Catch::alwaysTrue() true
Catch::alwaysTrue() true
Catch::alwaysTrue() true
Catch::alwaysTrue() true
i := 2 true true
3 true true
tab == '\t' '\t' == '\t' newline == '\n' '\n' == '\n' carr_return == '\r' '\r' == '\r' form_feed == '\f' '\f' == '\f'
space == ' ' ' ' == ' ' c == chars[i] 'a' == 'a' c == chars[i] 'z' == 'z' c == chars[i] 'A' == 'A' c == chars[i] 'Z' == 'Z'
null_terminator == '\0' 0 == 0 c == i 2 == 2 c == i 3 == 3 c == i 4 == 4 c == i 5 == 5
a 0x a == &foo 0x == 0x m == &S::f 0x == 0x 54 == 6*9 54 == 54 ( -1 > 2u ) true -1 > 2u -1 > 2 ( 2u < -1 ) true 2u < -1 2 < -1 ( minInt > 2u ) true minInt > 2u -2147483648 > 2 i == 1 1 == 1 ui == 2 2 == 2 l == 3 3 == 3 ul == 4 4 == 4 c == 5 5 == 5 uc == 6 6 == 6 1 == i 1 == 1 2 == ui 2 == 2 3 == l 3 == 3 4 == ul 4 == 4 5 == c 5 == 5 6 == uc 6 == 6 (std::numeric_limits<unsigned long>::max)() > ul 18446744073709551615 (0x) > 4 testStringForMatching(), Contains( "not there" ) "this string contains 'abc' as a substring" contains: "not there" throwCustom() throwCustom() custom exception - not std throwCustom(), std::exception throwCustom(), std::exception custom exception - not std custom std exception t == 1u {?} == 1 testStringForMatching(), EndsWith( "this" ) "this string contains 'abc' as a substring" ends with: "this" data.int_seven == 6 7 == 6 data.int_seven == 8 7 == 8 data.int_seven == 0 7 == 0 data.float_nine_point_one == Approx( 9.11f ) 9.1f == Approx( 9.1099996567 ) data.float_nine_point_one == Approx( 9.0f ) 9.1f == Approx( 9.0 ) data.float_nine_point_one == Approx( 1 ) 9.1f == Approx( 1.0 ) data.float_nine_point_one == Approx( 0 ) 9.1f == Approx( 0.0 ) data.double_pi == Approx( 3.1415 ) 3.1415926535 == Approx( 3.1415 ) data.str_hello == "goodbye" "hello" == "goodbye" data.str_hello == "hell" "hello" == "hell" data.str_hello == "hello1" "hello" == "hello1" data.str_hello.size() == 6 5 == 6 x == Approx( 1.301 ) 1.3 == Approx( 1.301 ) data.int_seven == 7 7 == 7 data.float_nine_point_one == Approx( 9.1f ) 9.1f == Approx( 9.1000003815 ) data.double_pi == Approx( 3.1415926535 ) 3.1415926535 == Approx( 3.1415926535 ) data.str_hello == "hello" "hello" == "hello" "hello" == data.str_hello "hello" == "hello" data.str_hello.size() == 5 5 == 5 x == Approx( 1.3 ) 1.3 == Approx( 1.3 ) testStringForMatching(), Equals( "this string contains 'abc' as a substring" ) "this string contains 'abc' as a substring" equals: "this string contains 'abc' as a substring" testStringForMatching(), Equals( "something else" ) "this string contains 'abc' as a substring" equals: "something else"
thisThrows(), "expected exception" thisThrows(), "expected exception"
thisThrows(), Equals( "expecteD Exception", Catch::CaseSensitive::No ) thisThrows(), Equals( "expecteD Exception", Catch::CaseSensitive::No )
thisThrows(), StartsWith( "expected" ) thisThrows(), StartsWith( "expected" ) thisThrows(), EndsWith( "exception" ) thisThrows(), EndsWith( "exception" ) thisThrows(), Contains( "except" ) thisThrows(), Contains( "except" ) thisThrows(), Contains( "exCept", Catch::CaseSensitive::No ) thisThrows(), Contains( "exCept", Catch::CaseSensitive::No )
thisThrows(), std::string thisThrows(), std::string expected exception thisDoesntThrow(), std::domain_error thisDoesntThrow(), std::domain_error thisThrows() thisThrows() expected exception This is a failure This is a failure This message appears in the output Factorial(0) == 1 1 == 1 Factorial(1) == 1 1 == 1 Factorial(2) == 2 2 == 2 Factorial(3) == 6 6 == 6 Factorial(10) == 3628800 3628800 (0x) == 3628800 (0x) i->first == i->second-1 0 == 0 i->first == i->second-1 2 == 2 multiply( i, 2 ) == i*2 2 == 2 multiply( j, 2 ) == j*2 200 == 200 multiply( i, 2 ) == i*2 4 == 4 multiply( j, 2 ) == j*2 200 == 200 multiply( i, 2 ) == i*2 6 == 6 multiply( j, 2 ) == j*2 200 == 200 multiply( i, 2 ) == i*2 8 == 8 multiply( j, 2 ) == j*2 200 == 200 multiply( i, 2 ) == i*2 10 == 10 multiply( j, 2 ) == j*2 200 == 200 multiply( i, 2 ) == i*2 30 == 30 multiply( j, 2 ) == j*2 200 == 200 multiply( i, 2 ) == i*2 40 == 40 multiply( j, 2 ) == j*2 200 == 200 multiply( i, 2 ) == i*2 42 == 42 multiply( j, 2 ) == j*2 200 == 200 multiply( i, 2 ) == i*2 72 == 72 multiply( j, 2 ) == j*2 200 == 200 multiply( i, 2 ) == i*2 2 == 2 multiply( j, 2 ) == j*2 202 == 202 multiply( i, 2 ) == i*2 4 == 4 multiply( j, 2 ) == j*2 202 == 202 multiply( i, 2 ) == i*2 6 == 6 multiply( j, 2 ) == j*2 202 == 202 multiply( i, 2 ) == i*2 8 == 8 multiply( j, 2 ) == j*2 202 == 202 multiply( i, 2 ) == i*2 10 == 10 multiply( j, 2 ) == j*2 202 == 202 multiply( i, 2 ) == i*2 30 == 30 multiply( j, 2 ) == j*2 202 == 202 multiply( i, 2 ) == i*2 40 == 40 multiply( j, 2 ) == j*2 202 == 202 multiply( i, 2 ) == i*2 42 == 42 multiply( j, 2 ) == j*2 202 == 202 multiply( i, 2 ) == i*2 72 == 72 multiply( j, 2 ) == j*2 202 == 202 multiply( i, 2 ) == i*2 2 == 2 multiply( j, 2 ) == j*2 204 == 204 multiply( i, 2 ) == i*2 4 == 4 multiply( j, 2 ) == j*2 204 == 204 multiply( i, 2 ) == i*2 6 == 6 multiply( j, 2 ) == j*2 204 == 204 multiply( i, 2 ) == i*2 8 == 8 multiply( j, 2 ) == j*2 204 == 204 multiply( i, 2 ) == i*2 10 == 10 multiply( j, 2 ) == j*2 204 == 204 multiply( i, 2 ) == i*2 30 == 30 multiply( j, 2 ) == j*2 204 == 204 multiply( i, 2 ) == i*2 40 == 40 multiply( j, 2 ) == j*2 204 == 204 multiply( i, 2 ) == i*2 42 == 42 multiply( j, 2 ) == j*2 204 == 204 multiply( i, 2 ) == i*2 72 == 72 multiply( j, 2 ) == j*2 204 == 204 multiply( i, 2 ) == i*2 2 == 2 multiply( j, 2 ) == j*2 206 == 206 multiply( i, 2 ) == i*2 4 == 4 multiply( j, 2 ) == j*2 206 == 206 multiply( i, 2 ) == i*2 6 == 6 multiply( j, 2 ) == j*2 206 == 206 multiply( i, 2 ) == i*2 8 == 8 multiply( j, 2 ) == j*2 206 == 206 multiply( i, 2 ) == i*2 10 == 10 multiply( j, 2 ) == j*2 206 == 206 multiply( i, 2 ) == i*2 30 == 30 multiply( j, 2 ) == j*2 206 == 206 multiply( i, 2 ) == i*2 40 == 40 multiply( j, 2 ) == j*2 206 == 206 multiply( i, 2 ) == i*2 42 == 42 multiply( j, 2 ) == j*2 206 == 206 multiply( i, 2 ) == i*2 72 == 72 multiply( j, 2 ) == j*2 206 == 206 multiply( i, 2 ) == i*2 2 == 2 multiply( j, 2 ) == j*2 208 == 208 multiply( i, 2 ) == i*2 4 == 4 multiply( j, 2 ) == j*2 208 == 208 multiply( i, 2 ) == i*2 6 == 6 multiply( j, 2 ) == j*2 208 == 208 multiply( i, 2 ) == i*2 8 == 8 multiply( j, 2 ) == j*2 208 == 208 multiply( i, 2 ) == i*2 10 == 10 multiply( j, 2 ) == j*2 208 == 208 multiply( i, 2 ) == i*2 30 == 30 multiply( j, 2 ) == j*2 208 == 208 multiply( i, 2 ) == i*2 40 == 40 multiply( j, 2 ) == j*2 208 == 208 multiply( i, 2 ) == i*2 42 == 42 multiply( j, 2 ) == j*2 208 == 208 multiply( i, 2 ) == i*2 72 == 72 multiply( j, 2 ) == j*2 208 == 208 multiply( i, 2 ) == i*2 2 == 2 multiply( j, 2 ) == j*2 210 == 210 multiply( i, 2 ) == i*2 4 == 4 multiply( j, 2 ) == j*2 210 == 210 multiply( i, 2 ) == i*2 6 == 6 multiply( j, 2 ) == j*2 210 == 210 multiply( i, 2 ) == i*2 8 == 8 multiply( j, 2 ) == j*2 210 == 210 multiply( i, 2 ) == i*2 10 == 10 multiply( j, 2 ) == j*2 210 == 210 multiply( i, 2 ) == i*2 30 == 30 multiply( j, 2 ) == j*2 210 == 210 multiply( i, 2 ) == i*2 40 == 40 multiply( j, 2 ) == j*2 210 == 210 multiply( i, 2 ) == i*2 42 == 42 multiply( j, 2 ) == j*2 210 == 210 multiply( i, 2 ) == i*2 72 == 72 multiply( j, 2 ) == j*2 210 == 210 multiply( i, 2 ) == i*2 2 == 2 multiply( j, 2 ) == j*2 212 == 212 multiply( i, 2 ) == i*2 4 == 4 multiply( j, 2 ) == j*2 212 == 212 multiply( i, 2 ) == i*2 6 == 6 multiply( j, 2 ) == j*2 212 == 212 multiply( i, 2 ) == i*2 8 == 8 multiply( j, 2 ) == j*2 212 == 212 multiply( i, 2 ) == i*2 10 == 10 multiply( j, 2 ) == j*2 212 == 212 multiply( i, 2 ) == i*2 30 == 30 multiply( j, 2 ) == j*2 212 == 212 multiply( i, 2 ) == i*2 40 == 40 multiply( j, 2 ) == j*2 212 == 212 multiply( i, 2 ) == i*2 42 == 42 multiply( j, 2 ) == j*2 212 == 212 multiply( i, 2 ) == i*2 72 == 72 multiply( j, 2 ) == j*2 212 == 212 multiply( i, 2 ) == i*2 2 == 2 multiply( j, 2 ) == j*2 214 == 214 multiply( i, 2 ) == i*2 4 == 4 multiply( j, 2 ) == j*2 214 == 214 multiply( i, 2 ) == i*2 6 == 6 multiply( j, 2 ) == j*2 214 == 214 multiply( i, 2 ) == i*2 8 == 8 multiply( j, 2 ) == j*2 214 == 214 multiply( i, 2 ) == i*2 10 == 10 multiply( j, 2 ) == j*2 214 == 214 multiply( i, 2 ) == i*2 30 == 30 multiply( j, 2 ) == j*2 214 == 214 multiply( i, 2 ) == i*2 40 == 40 multiply( j, 2 ) == j*2 214 == 214 multiply( i, 2 ) == i*2 42 == 42 multiply( j, 2 ) == j*2 214 == 214 multiply( i, 2 ) == i*2 72 == 72 multiply( j, 2 ) == j*2 214 == 214 d >= Approx( 1.22 ) 1.23 >= Approx( 1.22 ) d >= Approx( 1.23 ) 1.23 >= Approx( 1.23 ) !(d >= Approx( 1.24 )) !(1.23 >= Approx( 1.24 )) d >= Approx( 1.24 ).epsilon(0.1) 1.23 >= Approx( 1.24 ) this is a message this is a warning this message should be logged so should this a == 1 2 == 1 this message may be logged later a == 2 2 == 2 this message may be logged later this message should be logged a == 1 2 == 1 this message may be logged later this message should be logged and this, but later a == 0 2 == 0 this message may be logged later this message should be logged and this, but later but not this a == 2 2 == 2 data.int_seven != 7 7 != 7 data.float_nine_point_one != Approx( 9.1f ) 9.1f != Approx( 9.1000003815 ) data.double_pi != Approx( 3.1415926535 ) 3.1415926535 != Approx( 3.1415926535 ) data.str_hello != "hello" "hello" != "hello" data.str_hello.size() != 5 5 != 5 data.int_seven != 6 7 != 6 data.int_seven != 8 7 != 8 data.float_nine_point_one != Approx( 9.11f ) 9.1f != Approx( 9.1099996567 ) data.float_nine_point_one != Approx( 9.0f ) 9.1f != Approx( 9.0 ) data.float_nine_point_one != Approx( 1 ) 9.1f != Approx( 1.0 ) data.float_nine_point_one != Approx( 0 ) 9.1f != Approx( 0.0 ) data.double_pi != Approx( 3.1415 ) 3.1415926535 != Approx( 3.1415 ) data.str_hello != "goodbye" "hello" != "goodbye" data.str_hello != "hell" "hello" != "hell" data.str_hello != "hello1" "hello" != "hello1" data.str_hello.size() != 6 5 != 6 d <= Approx( 1.24 ) 1.23 <= Approx( 1.24 ) d <= Approx( 1.23 ) 1.23 <= Approx( 1.23 ) !(d <= Approx( 1.22 )) !(1.23 <= Approx( 1.22 )) d <= Approx( 1.22 ).epsilon(0.1) 1.23 <= Approx( 1.22 )
Text( testString, TextAttributes().setWidth( 80 ) ).toString() == testString "one two three four" == "one two three four" Text( testString, TextAttributes().setWidth( 18 ) ).toString() == testString "one two three four" == "one two three four"
Text( testString, TextAttributes().setWidth( 17 ) ).toString() == "one two three\nfour" "one two three four" == "one two three four" Text( testString, TextAttributes().setWidth( 16 ) ).toString() == "one two three\nfour" "one two three four" == "one two three four" Text( testString, TextAttributes().setWidth( 14 ) ).toString() == "one two three\nfour" "one two three four" == "one two three four" Text( testString, TextAttributes().setWidth( 13 ) ).toString() == "one two three\nfour" "one two three four" == "one two three four" Text( testString, TextAttributes().setWidth( 12 ) ).toString() == "one two\nthree four" "one two three four" == "one two three four"
Text( testString, TextAttributes().setWidth( 9 ) ).toString() == "one two\nthree\nfour" "one two three four" == "one two three four" Text( testString, TextAttributes().setWidth( 8 ) ).toString() == "one two\nthree\nfour" "one two three four" == "one two three four" Text( testString, TextAttributes().setWidth( 7 ) ).toString() == "one two\nthree\nfour" "one two three four" == "one two three four"
Text( testString, TextAttributes().setWidth( 6 ) ).toString() == "one\ntwo\nthree\nfour" "one two three four" == "one two three four" Text( testString, TextAttributes().setWidth( 5 ) ).toString() == "one\ntwo\nthree\nfour" "one two three four" == "one two three four"
Text( "abcdef", TextAttributes().setWidth( 4 ) ).toString() == "abc-\ndef" "abc- def" == "abc- def" Text( "abcdefg", TextAttributes().setWidth( 4 ) ).toString() == "abc-\ndefg" "abc- defg" == "abc- defg" Text( "abcdefgh", TextAttributes().setWidth( 4 ) ).toString() == "abc-\ndef-\ngh" "abc- def- gh" == "abc- def- gh" Text( testString, TextAttributes().setWidth( 4 ) ).toString() == "one\ntwo\nthr-\nee\nfour" "one two thr- ee four" == "one two thr- ee four" Text( testString, TextAttributes().setWidth( 3 ) ).toString() == "one\ntwo\nth-\nree\nfo-\nur" "one two th- ree fo- ur" == "one two th- ree fo- ur"
text.size() == 4 4 == 4 text[0] == "one" "one" == "one" text[1] == "two" "two" == "two" text[2] == "three" "three" == "three" text[3] == "four" "four" == "four"
text.toString() == " one two\n three\n four" " one two three four" == " one two three four"
Text( testString, TextAttributes().setWidth( 80 ) ).toString() == testString "one two three four" == "one two three four" Text( testString, TextAttributes().setWidth( 18 ) ).toString() == testString "one two three four" == "one two three four" Text( testString, TextAttributes().setWidth( 10 ) ).toString() == testString "one two three four" == "one two three four"
Text( "abcdef\n", TextAttributes().setWidth( 10 ) ).toString() == "abcdef" "abcdef" == "abcdef" Text( "abcdef", TextAttributes().setWidth( 6 ) ).toString() == "abcdef" "abcdef" == "abcdef" Text( "abcdef\n", TextAttributes().setWidth( 6 ) ).toString() == "abcdef" "abcdef" == "abcdef" Text( "abcdef\n", TextAttributes().setWidth( 5 ) ).toString() == "abcd-\nef" "abcd- ef" == "abcd- ef"
Text( testString, TextAttributes().setWidth( 9 ) ).toString() == "one two\nthree\nfour" "one two three four" == "one two three four" Text( testString, TextAttributes().setWidth( 8 ) ).toString() == "one two\nthree\nfour" "one two three four" == "one two three four" Text( testString, TextAttributes().setWidth( 7 ) ).toString() == "one two\nthree\nfour" "one two three four" == "one two three four"
Text( testString, TextAttributes().setWidth( 6 ) ).toString() == "one\ntwo\nthree\nfour" "one two three four" == "one two three four"
Text( testString, TextAttributes().setWidth( 80 ) ).toString() == testString "one,two(three) <here>" == "one,two(three) <here>" Text( testString, TextAttributes().setWidth( 24 ) ).toString() == testString "one,two(three) <here>" == "one,two(three) <here>"
Text( testString, TextAttributes().setWidth( 11 ) ).toString() == "one,two\n(three)\n<here>" "one,two (three) <here>" == "one,two (three) <here>"
Text( testString, TextAttributes().setWidth( 6 ) ).toString() == "one,\ntwo\n(thre-\ne)\n<here>" "one, two (thre- e) <here>" == "one, two (thre- e) <here>" Text( testString, TextAttributes().setWidth( 5 ) ).toString() == "one,\ntwo\n(thr-\nee)\n<her-\ne>" "one, two (thr- ee) <her- e>" == "one, two (thr- ee) <her- e>" Text( testString, TextAttributes().setWidth( 4 ) ).toString() == "one,\ntwo\n(th-\nree)\n<he-\nre>" "one, two (th- ree) <he- re>" == "one, two (th- ree) <he- re>"
t.toString(), EndsWith( "... message truncated due to excessive size" ) "******************************************************************************- ******************************************************************************- ************************ ******************************************************************************- ******************************************************************************- ************************ ******************************************************************************- ******************************************************************************- ************************ ******************************************************************************- ******************************************************************************- ************************ ******************************************************************************- ******************************************************************************- ************************ ******************************************************************************- ******************************************************************************- ************************ ******************************************************************************- ******************************************************************************- ************************ ******************************************************************************- ******************************************************************************- ************************ ******************************************************************************- ******************************************************************************- ************************ ******************************************************************************- ******************************************************************************- ************************ ******************************************************************************- ******************************************************************************- ************************ ******************************************************************************- ******************************************************************************- ************************ ******************************************************************************- ******************************************************************************- ************************ ******************************************************************************- ******************************************************************************- ************************ ******************************************************************************- ******************************************************************************- ************************ ******************************************************************************- ******************************************************************************- ************************ ******************************************************************************- ******************************************************************************- ************************ ******************************************************************************- ******************************************************************************- ************************ ******************************************************************************- ******************************************************************************- ************************ ******************************************************************************- ******************************************************************************- ************************ ******************************************************************************- ******************************************************************************- ************************ ******************************************************************************- ******************************************************************************- ************************ ******************************************************************************- ******************************************************************************- ************************ ******************************************************************************- ******************************************************************************- ************************ ******************************************************************************- ******************************************************************************- ************************ ******************************************************************************- ******************************************************************************- ************************ ******************************************************************************- ******************************************************************************- ************************ ******************************************************************************- ******************************************************************************- ************************ ******************************************************************************- ******************************************************************************- ************************ ******************************************************************************- ******************************************************************************- ************************ ******************************************************************************- ******************************************************************************- ************************ ******************************************************************************- ******************************************************************************- ************************ ******************************************************************************- ******************************************************************************- ************************ ******************************************************************************- ******************************************************************************- ************************ ******************************************************************************- ******************************************************************************- ************************ ******************************************************************************- ******************************************************************************- ************************ ******************************************************************************- ******************************************************************************- ************************ ******************************************************************************- ******************************************************************************- ************************ ******************************************************************************- ******************************************************************************- ************************ ******************************************************************************- ******************************************************************************- ************************ ******************************************************************************- ******************************************************************************- ************************ ******************************************************************************- ******************************************************************************- ************************ ******************************************************************************- ******************************************************************************- ************************ ******************************************************************************- ******************************************************************************- ************************ ******************************************************************************- ******************************************************************************- ************************ ******************************************************************************- ******************************************************************************- ************************ ******************************************************************************- ******************************************************************************- ************************ ******************************************************************************- ******************************************************************************- ************************ ******************************************************************************- ******************************************************************************- ************************ ******************************************************************************- ******************************************************************************- ************************ ******************************************************************************- ******************************************************************************- ************************ ******************************************************************************- ******************************************************************************- ************************ ******************************************************************************- ******************************************************************************- ************************ ******************************************************************************- ******************************************************************************- ************************ ******************************************************************************- ******************************************************************************- ************************ ******************************************************************************- ******************************************************************************- ************************ ******************************************************************************- ******************************************************************************- ************************ ******************************************************************************- ******************************************************************************- ************************ ******************************************************************************- ******************************************************************************- ************************ ******************************************************************************- ******************************************************************************- ************************ ******************************************************************************- ******************************************************************************- ************************ ******************************************************************************- ******************************************************************************- ************************ ******************************************************************************- ******************************************************************************- ************************ ******************************************************************************- ******************************************************************************- ************************ ******************************************************************************- ******************************************************************************- ************************ ******************************************************************************- ******************************************************************************- ************************ ******************************************************************************- ******************************************************************************- ************************ ******************************************************************************- ******************************************************************************- ************************ ******************************************************************************- ******************************************************************************- ************************ ******************************************************************************- ******************************************************************************- ************************ ******************************************************************************- ******************************************************************************- ************************ ******************************************************************************- ******************************************************************************- ************************ ******************************************************************************- ******************************************************************************- ************************ ******************************************************************************- ******************************************************************************- ************************ ******************************************************************************- ******************************************************************************- ************************ ******************************************************************************- ******************************************************************************- ************************ ******************************************************************************- ******************************************************************************- ************************ ******************************************************************************- ******************************************************************************- ************************ ******************************************************************************- ******************************************************************************- ************************ ******************************************************************************- ******************************************************************************- ************************ ******************************************************************************- ******************************************************************************- ************************ ******************************************************************************- ******************************************************************************- ************************ ******************************************************************************- ******************************************************************************- ************************ ******************************************************************************- ******************************************************************************- ************************ ******************************************************************************- ******************************************************************************- ************************ ******************************************************************************- ******************************************************************************- ************************ ******************************************************************************- ******************************************************************************- ************************ ******************************************************************************- ******************************************************************************- ************************ ******************************************************************************- ******************************************************************************- ************************ ******************************************************************************- ******************************************************************************- ************************ ******************************************************************************- ******************************************************************************- ************************ ******************************************************************************- ******************************************************************************- ************************ ******************************************************************************- ******************************************************************************- ************************ ******************************************************************************- ******************************************************************************- ************************ ******************************************************************************- ******************************************************************************- ************************ ******************************************************************************- ******************************************************************************- ************************ ******************************************************************************- ******************************************************************************- ************************ ******************************************************************************- ******************************************************************************- ************************ ******************************************************************************- ******************************************************************************- ************************ ******************************************************************************- ******************************************************************************- ************************ ******************************************************************************- ******************************************************************************- ************************ ******************************************************************************- ******************************************************************************- ************************ ******************************************************************************- ******************************************************************************- ************************ ******************************************************************************- ******************************************************************************- ************************ ******************************************************************************- ******************************************************************************- ************************ ******************************************************************************- ******************************************************************************- ************************ ******************************************************************************- ******************************************************************************- ************************ ******************************************************************************- ******************************************************************************- ************************ ******************************************************************************- ******************************************************************************- ************************ ******************************************************************************- ******************************************************************************- ************************ ******************************************************************************- ******************************************************************************- ************************ ******************************************************************************- ******************************************************************************- ************************ ******************************************************************************- ******************************************************************************- ************************ ******************************************************************************- ******************************************************************************- ************************ ******************************************************************************- ******************************************************************************- ************************ ******************************************************************************- ******************************************************************************- ************************ ******************************************************************************- ******************************************************************************- ************************ ******************************************************************************- ******************************************************************************- ************************ ******************************************************************************- ******************************************************************************- ************************ ******************************************************************************- ******************************************************************************- ************************ ******************************************************************************- ******************************************************************************- ************************ ******************************************************************************- ******************************************************************************- ************************ ******************************************************************************- ******************************************************************************- ************************ ******************************************************************************- ******************************************************************************- ************************ ******************************************************************************- ******************************************************************************- ************************ ******************************************************************************- ******************************************************************************- ************************ ******************************************************************************- ******************************************************************************- ************************ ******************************************************************************- ******************************************************************************- ************************ ******************************************************************************- ******************************************************************************- ************************ ******************************************************************************- ******************************************************************************- ************************ ******************************************************************************- ******************************************************************************- ************************ ******************************************************************************- ******************************************************************************- ************************ ******************************************************************************- ******************************************************************************- ************************ ******************************************************************************- ******************************************************************************- ************************ ******************************************************************************- ******************************************************************************- ************************ ******************************************************************************- ******************************************************************************- ************************ ******************************************************************************- ******************************************************************************- ************************ ******************************************************************************- ******************************************************************************- ************************ ******************************************************************************- ******************************************************************************- ************************ ******************************************************************************- ******************************************************************************- ************************ ******************************************************************************- ******************************************************************************- ************************ ******************************************************************************- ******************************************************************************- ************************ ******************************************************************************- ******************************************************************************- ************************ ******************************************************************************- ******************************************************************************- ************************ ******************************************************************************- ******************************************************************************- ************************ ******************************************************************************- ******************************************************************************- ************************ ******************************************************************************- ******************************************************************************- ************************ ******************************************************************************- ******************************************************************************- ************************ ******************************************************************************- ******************************************************************************- ************************ ******************************************************************************- ******************************************************************************- ************************ ******************************************************************************- ******************************************************************************- ************************ ******************************************************************************- ******************************************************************************- ************************ ******************************************************************************- ******************************************************************************- ************************ ******************************************************************************- ******************************************************************************- ************************ ******************************************************************************- ******************************************************************************- ************************ ******************************************************************************- ******************************************************************************- ************************ ******************************************************************************- ******************************************************************************- ************************ ******************************************************************************- ******************************************************************************- ************************ ******************************************************************************- ******************************************************************************- ************************ ******************************************************************************- ******************************************************************************- ************************ ******************************************************************************- ******************************************************************************- ************************ ******************************************************************************- ******************************************************************************- ************************ ******************************************************************************- ******************************************************************************- ************************ ******************************************************************************- ******************************************************************************- ************************ ******************************************************************************- ******************************************************************************- ************************ ******************************************************************************- ******************************************************************************- ************************ ******************************************************************************- ******************************************************************************- ************************ ******************************************************************************- ******************************************************************************- ************************ ******************************************************************************- ******************************************************************************- ************************ ******************************************************************************- ******************************************************************************- ************************ ******************************************************************************- ******************************************************************************- ************************ ******************************************************************************- ******************************************************************************- ************************ ******************************************************************************- ******************************************************************************- ************************ ******************************************************************************- ******************************************************************************- ************************ ******************************************************************************- ******************************************************************************- ************************ ******************************************************************************- ******************************************************************************- ************************ ******************************************************************************- ******************************************************************************- ************************ ******************************************************************************- ******************************************************************************- ************************ ******************************************************************************- ******************************************************************************- ************************ ******************************************************************************- ******************************************************************************- ************************ ******************************************************************************- ******************************************************************************- ************************ ******************************************************************************- ******************************************************************************- ************************ ******************************************************************************- ******************************************************************************- ************************ ******************************************************************************- ******************************************************************************- ************************ ******************************************************************************- ******************************************************************************- ************************ ******************************************************************************- ******************************************************************************- ************************ ******************************************************************************- ******************************************************************************- ************************ ******************************************************************************- ******************************************************************************- ************************ ******************************************************************************- ******************************************************************************- ************************ ******************************************************************************- ******************************************************************************- ************************ ******************************************************************************- ******************************************************************************- ************************ ******************************************************************************- ******************************************************************************- ************************ ******************************************************************************- ******************************************************************************- ************************ ******************************************************************************- ******************************************************************************- ************************ ******************************************************************************- ******************************************************************************- ************************ ******************************************************************************- ******************************************************************************- ************************ ******************************************************************************- ******************************************************************************- ************************ ******************************************************************************- ******************************************************************************- ************************ ******************************************************************************- ******************************************************************************- ************************ ******************************************************************************- ******************************************************************************- ************************ ******************************************************************************- ******************************************************************************- ************************ ******************************************************************************- ******************************************************************************- ************************ ******************************************************************************- ******************************************************************************- ************************ ******************************************************************************- ******************************************************************************- ************************ ******************************************************************************- ******************************************************************************- ************************ ******************************************************************************- ******************************************************************************- ************************ ******************************************************************************- ******************************************************************************- ************************ ******************************************************************************- ******************************************************************************- ************************ ******************************************************************************- ******************************************************************************- ************************ ******************************************************************************- ******************************************************************************- ************************ ******************************************************************************- ******************************************************************************- ************************ ******************************************************************************- ******************************************************************************- ************************ ******************************************************************************- ******************************************************************************- ************************ ******************************************************************************- ******************************************************************************- ************************ ******************************************************************************- ******************************************************************************- ************************ ******************************************************************************- ******************************************************************************- ************************ ******************************************************************************- ******************************************************************************- ************************ ******************************************************************************- ******************************************************************************- ************************ ******************************************************************************- ******************************************************************************- ************************ ******************************************************************************- ******************************************************************************- ************************ ******************************************************************************- ******************************************************************************- ************************ ******************************************************************************- ******************************************************************************- ************************ ******************************************************************************- ******************************************************************************- ************************ ******************************************************************************- ******************************************************************************- ************************ ******************************************************************************- ******************************************************************************- ************************ ******************************************************************************- ******************************************************************************- ************************ ******************************************************************************- ******************************************************************************- ************************ ******************************************************************************- ******************************************************************************- ************************ ******************************************************************************- ******************************************************************************- ************************ ******************************************************************************- ******************************************************************************- ************************ ******************************************************************************- ******************************************************************************- ************************ ******************************************************************************- ******************************************************************************- ************************ ******************************************************************************- ******************************************************************************- ************************ ******************************************************************************- ******************************************************************************- ************************ ******************************************************************************- ******************************************************************************- ************************ ******************************************************************************- ******************************************************************************- ************************ ******************************************************************************- ******************************************************************************- ************************ ******************************************************************************- ******************************************************************************- ************************ ******************************************************************************- ******************************************************************************- ************************ ******************************************************************************- ******************************************************************************- ************************ ******************************************************************************- ******************************************************************************- ************************ ******************************************************************************- ******************************************************************************- ************************ ******************************************************************************- ******************************************************************************- ************************ ******************************************************************************- ******************************************************************************- ************************ ******************************************************************************- ******************************************************************************- ************************ ******************************************************************************- ******************************************************************************- ************************ ******************************************************************************- ******************************************************************************- ************************ ******************************************************************************- ******************************************************************************- ************************ ******************************************************************************- ******************************************************************************- ************************ ******************************************************************************- ******************************************************************************- ************************ ******************************************************************************- ******************************************************************************- ************************ ******************************************************************************- ******************************************************************************- ************************ ******************************************************************************- ******************************************************************************- ************************ ******************************************************************************- ******************************************************************************- ************************ ******************************************************************************- ******************************************************************************- ************************ ******************************************************************************- ******************************************************************************- ************************ ******************************************************************************- ******************************************************************************- ************************ ******************************************************************************- ******************************************************************************- ************************ ******************************************************************************- ******************************************************************************- ************************ ******************************************************************************- ******************************************************************************- ************************ ******************************************************************************- ******************************************************************************- ************************ ******************************************************************************- ******************************************************************************- ************************ ******************************************************************************- ******************************************************************************- ************************ ******************************************************************************- ******************************************************************************- ************************ ******************************************************************************- ******************************************************************************- ************************ ******************************************************************************- ******************************************************************************- ************************ ******************************************************************************- ******************************************************************************- ************************ ******************************************************************************- ******************************************************************************- ************************ ******************************************************************************- ******************************************************************************- ************************ ******************************************************************************- ******************************************************************************- ************************ ******************************************************************************- ******************************************************************************- ************************ ******************************************************************************- ******************************************************************************- ************************ ******************************************************************************- ******************************************************************************- ************************ ******************************************************************************- ******************************************************************************- ************************ ******************************************************************************- ******************************************************************************- ************************ ******************************************************************************- ******************************************************************************- ************************ ******************************************************************************- ******************************************************************************- ************************ ******************************************************************************- ******************************************************************************- ************************ ******************************************************************************- ******************************************************************************- ************************ ******************************************************************************- ******************************************************************************- ************************ ******************************************************************************- ******************************************************************************- ************************ ******************************************************************************- ******************************************************************************- ************************ ******************************************************************************- ******************************************************************************- ************************ ******************************************************************************- ******************************************************************************- ************************ ******************************************************************************- ******************************************************************************- ************************ ******************************************************************************- ******************************************************************************- ************************ ******************************************************************************- ******************************************************************************- ************************ ******************************************************************************- ******************************************************************************- ************************ ******************************************************************************- ******************************************************************************- ************************ ******************************************************************************- ******************************************************************************- ************************ ******************************************************************************- ******************************************************************************- ************************ ******************************************************************************- ******************************************************************************- ************************ ******************************************************************************- ******************************************************************************- ************************ ******************************************************************************- ******************************************************************************- ************************ ******************************************************************************- ******************************************************************************- ************************ ******************************************************************************- ******************************************************************************- ************************ ******************************************************************************- ******************************************************************************- ************************ ******************************************************************************- ******************************************************************************- ************************ ******************************************************************************- ******************************************************************************- ************************ ******************************************************************************- ******************************************************************************- ************************ ******************************************************************************- ******************************************************************************- ************************ ******************************************************************************- ******************************************************************************- ************************ ******************************************************************************- ******************************************************************************- ************************ ******************************************************************************- ******************************************************************************- ************************ ******************************************************************************- ******************************************************************************- ************************ ******************************************************************************- ******************************************************************************- ************************ ******************************************************************************- ******************************************************************************- ************************ ******************************************************************************- ******************************************************************************- ************************ ******************************************************************************- ******************************************************************************- ************************ ******************************************************************************- ******************************************************************************- ************************ ******************************************************************************- ******************************************************************************- ************************ ******************************************************************************- ******************************************************************************- ************************ ******************************************************************************- ******************************************************************************- ************************ ******************************************************************************- ******************************************************************************- ************************ ******************************************************************************- ******************************************************************************- ************************ ******************************************************************************- ******************************************************************************- ************************ ******************************************************************************- ******************************************************************************- ************************ ******************************************************************************- ******************************************************************************- ************************ ******************************************************************************- ******************************************************************************- ************************ ******************************************************************************- ******************************************************************************- ************************ ******************************************************************************- ******************************************************************************- ************************ ******************************************************************************- ******************************************************************************- ************************ ******************************************************************************- ******************************************************************************- ************************ ******************************************************************************- ******************************************************************************- ************************ ******************************************************************************- ******************************************************************************- ************************ ******************************************************************************- ******************************************************************************- ************************ ******************************************************************************- ******************************************************************************- ************************ ******************************************************************************- ******************************************************************************- ************************ ******************************************************************************- ******************************************************************************- ************************ ******************************************************************************- ******************************************************************************- ************************ ******************************************************************************- ******************************************************************************- ************************ ******************************************************************************- ******************************************************************************- ************************ ******************************************************************************- ******************************************************************************- ************************ ******************************************************************************- ... message truncated due to excessive size" ends with: "... message truncated due to excessive size" testStringForMatching(), Contains( "string" ) && Contains( "abc" ) && Contains( "substring" ) && Contains( "contains" ) "this string contains 'abc' as a substring" ( contains: "string" and contains: "abc" and contains: "substring" and contains: "contains" ) testStringForMatching(), Contains( "string" ) || Contains( "different" ) || Contains( "random" ) "this string contains 'abc' as a substring" ( contains: "string" or contains: "different" or contains: "random" ) testStringForMatching2(), Contains( "string" ) || Contains( "different" ) || Contains( "random" ) "some completely different text that contains one common word" ( contains: "string" or contains: "different" or contains: "random" ) testStringForMatching(), ( Contains( "string" ) || Contains( "different" ) ) && Contains( "substring" ) "this string contains 'abc' as a substring" ( ( contains: "string" or contains: "different" ) and contains: "substring" ) testStringForMatching(), ( Contains( "string" ) || Contains( "different" ) ) && Contains( "random" ) "this string contains 'abc' as a substring" ( ( contains: "string" or contains: "different" ) and contains: "random" ) testStringForMatching(), !Contains( "different" ) "this string contains 'abc' as a substring" not contains: "different" testStringForMatching(), !Contains( "substring" ) "this string contains 'abc' as a substring" not contains: "substring" thisThrows(), "expected exception" thisThrows(), "expected exception" thisThrows(), "should fail" expected exception This one ran custom exception thisFunctionNotImplemented( 7 ) thisFunctionNotImplemented( 7 ) True 1 !False true !(False) !0 0x == o 3221225472 (0x) == {?} data.int_seven > 7 7 > 7 data.int_seven < 7 7 < 7 data.int_seven > 8 7 > 8 data.int_seven < 6 7 < 6 data.int_seven < 0 7 < 0 data.int_seven < -1 7 < -1 data.int_seven >= 8 7 >= 8 data.int_seven <= 6 7 <= 6 data.float_nine_point_one < 9 9.1f < 9 data.float_nine_point_one > 10 9.1f > 10 data.float_nine_point_one > 9.2 9.1f > 9.2 data.str_hello > "hello" "hello" > "hello" data.str_hello < "hello" "hello" < "hello" data.str_hello > "hellp" "hello" > "hellp" data.str_hello > "z" "hello" > "z" data.str_hello < "hellm" "hello" < "hellm" data.str_hello < "a" "hello" < "a" data.str_hello >= "z" "hello" >= "z" data.str_hello <= "a" "hello" <= "a" data.int_seven < 8 7 < 8 data.int_seven > 6 7 > 6 data.int_seven > 0 7 > 0 data.int_seven > -1 7 > -1 data.int_seven >= 7 7 >= 7 data.int_seven >= 6 7 >= 6 data.int_seven <= 7 7 <= 7 data.int_seven <= 8 7 <= 8 data.float_nine_point_one > 9 9.1f > 9 data.float_nine_point_one < 10 9.1f < 10 data.float_nine_point_one < 9.2 9.1f < 9.2 data.str_hello <= "hello" "hello" <= "hello" data.str_hello >= "hello" "hello" >= "hello" data.str_hello < "hellp" "hello" < "hellp" data.str_hello < "zebra" "hello" < "zebra" data.str_hello > "hellm" "hello" > "hellm" data.str_hello > "a" "hello" > "a"
Message from section one
Message from section two
spec.hasFilters() == false false == false spec.matches( tcA ) == false false == false spec.matches( tcB ) == false false == false
spec.hasFilters() == false false == false spec.matches(tcA ) == false false == false spec.matches( tcB ) == false false == false
spec.hasFilters() == false false == false spec.matches( tcA ) == false false == false spec.matches( tcB ) == false false == false
spec.hasFilters() == true true == true spec.matches( tcA ) == false false == false spec.matches( tcB ) == true true == true
spec.hasFilters() == true true == true spec.matches( tcA ) == false false == false spec.matches( tcB ) == true true == true
spec.hasFilters() == true true == true spec.matches( tcA ) == false false == false spec.matches( tcB ) == true true == true spec.matches( tcC ) == false false == false
spec.hasFilters() == true true == true spec.matches( tcA ) == false false == false spec.matches( tcB ) == false false == false spec.matches( tcC ) == true true == true spec.matches( tcD ) == false false == false parseTestSpec( "*a" ).matches( tcA ) == true true == true
spec.hasFilters() == true true == true spec.matches( tcA ) == false false == false spec.matches( tcB ) == false false == false spec.matches( tcC ) == true true == true spec.matches( tcD ) == false false == false parseTestSpec( "a*" ).matches( tcA ) == true true == true
spec.hasFilters() == true true == true spec.matches( tcA ) == false false == false spec.matches( tcB ) == false false == false spec.matches( tcC ) == true true == true spec.matches( tcD ) == true true == true parseTestSpec( "*a*" ).matches( tcA ) == true true == true
spec.hasFilters() == true true == true spec.matches( tcA ) == true true == true spec.matches( tcB ) == false false == false
spec.hasFilters() == true true == true spec.matches( tcA ) == true true == true spec.matches( tcB ) == false false == false
spec.hasFilters() == true true == true spec.matches( tcA ) == true true == true spec.matches( tcB ) == false false == false
spec.hasFilters() == true true == true spec.matches( tcA ) == false false == false spec.matches( tcB ) == false false == false spec.matches( tcC ) == true true == true spec.matches( tcD ) == true true == true
spec.hasFilters() == true true == true spec.matches( tcA ) == true true == true spec.matches( tcB ) == true true == true spec.matches( tcC ) == true true == true spec.matches( tcD ) == true true == true
spec.hasFilters() == true true == true spec.matches( tcA ) == false false == false spec.matches( tcB ) == true true == true spec.matches( tcC ) == false false == false
spec.hasFilters() == true true == true spec.matches( tcA ) == false false == false spec.matches( tcB ) == true true == true spec.matches( tcC ) == true true == true
spec.hasFilters() == true true == true spec.matches( tcA ) == false false == false spec.matches( tcB ) == false false == false spec.matches( tcC ) == true true == true
spec.hasFilters() == true true == true spec.matches( tcA ) == false false == false spec.matches( tcB ) == false false == false spec.matches( tcC ) == true true == true
spec.hasFilters() == true true == true spec.matches( tcA ) == false false == false spec.matches( tcB ) == false false == false spec.matches( tcC ) == true true == true spec.matches( tcD ) == false false == false
spec.hasFilters() == true true == true spec.matches( tcA ) == true true == true spec.matches( tcB ) == false false == false spec.matches( tcC ) == true true == true
spec.hasFilters() == true true == true spec.matches( tcA ) == false false == false spec.matches( tcB ) == true true == true spec.matches( tcC ) == false false == false
spec.hasFilters() == true true == true spec.matches( tcA ) == false false == false spec.matches( tcB ) == false false == false spec.matches( tcC ) == false false == false spec.matches( tcD ) == true true == true
spec.hasFilters() == true true == true spec.matches( tcA ) == false false == false spec.matches( tcB ) == false false == false spec.matches( tcC ) == false false == false spec.matches( tcD ) == true true == true
spec.hasFilters() == true true == true spec.matches( tcA ) == true true == true spec.matches( tcB ) == false false == false spec.matches( tcC ) == true true == true spec.matches( tcD ) == true true == true
spec.hasFilters() == true true == true spec.matches( tcA ) == true true == true spec.matches( tcB ) == true true == true spec.matches( tcC ) == false false == false spec.matches( tcD ) == false false == false
spec.hasFilters() == true true == true spec.matches( tcA ) == true true == true spec.matches( tcB ) == true true == true spec.matches( tcC ) == true true == true spec.matches( tcD ) == false false == false
spec.hasFilters() == true true == true spec.matches( tcA ) == true true == true spec.matches( tcB ) == true true == true spec.matches( tcC ) == true true == true spec.matches( tcD ) == false false == false
spec.hasFilters() == true true == true spec.matches( tcA ) == false false == false spec.matches( tcB ) == false false == false spec.matches( tcC ) == true true == true spec.matches( tcD ) == false false == false
spec.hasFilters() == false false == false spec.matches( tcA ) == false false == false spec.matches( tcB ) == false false == false spec.matches( tcC ) == false false == false spec.matches( tcD ) == false false == false
spec.hasFilters() == false false == false spec.matches( tcA ) == false false == false spec.matches( tcB ) == false false == false spec.matches( tcC ) == false false == false spec.matches( tcD ) == false false == false
spec.hasFilters() == true true == true spec.matches( tcA ) == false false == false spec.matches( tcB ) == false false == false spec.matches( tcC ) == false false == false spec.matches( tcD ) == true true == true
(std::pair<int, int>( 1, 2 )) == aNicePair std::pair( 1, 2 ) == std::pair( 1, 2 ) p == 0 NULL == 0 p == pNULL NULL == NULL p != 0 0x != 0 cp != 0 0x != 0 cpc != 0 0x != 0 returnsNull() == 0 {null string} == 0 returnsConstNull() == 0 {null string} == 0 0 != p 0 != 0x actual address of p: 0x toString(p): 0x
parser.parseInto( std::vector<std::string>(), config ) parser.parseInto( std::vector<std::string>(), config ) config.processName == "" "" == ""
parseIntoConfig( argv, config ) parseIntoConfig( argv, config ) config.processName == "test" "test" == "test" config.shouldDebugBreak == false false == false config.abortAfter == -1 -1 == -1 config.noThrow == false false == false config.reporterNames.empty() true
parseIntoConfig( argv, config ) parseIntoConfig( argv, config ) cfg.testSpec().matches( fakeTestCase( "notIncluded" ) ) == false false == false cfg.testSpec().matches( fakeTestCase( "test1" ) ) true
parseIntoConfig( argv, config ) parseIntoConfig( argv, config ) cfg.testSpec().matches( fakeTestCase( "test1" ) ) == false false == false cfg.testSpec().matches( fakeTestCase( "alwaysIncluded" ) ) true
parseIntoConfig( argv, config ) parseIntoConfig( argv, config ) cfg.testSpec().matches( fakeTestCase( "test1" ) ) == false false == false cfg.testSpec().matches( fakeTestCase( "alwaysIncluded" ) ) true
parseIntoConfig( argv, config ) parseIntoConfig( argv, config ) config.reporterNames[0] == "console" "console" == "console"
parseIntoConfig( argv, config ) parseIntoConfig( argv, config ) config.reporterNames[0] == "xml" "xml" == "xml"
parseIntoConfig( argv, config ) parseIntoConfig( argv, config ) config.reporterNames.size() == 2 2 == 2 config.reporterNames[0] == "xml" "xml" == "xml" config.reporterNames[1] == "junit" "junit" == "junit"
parseIntoConfig( argv, config ) parseIntoConfig( argv, config ) config.reporterNames[0] == "junit" "junit" == "junit"
parseIntoConfig( argv, config ) parseIntoConfig( argv, config ) config.shouldDebugBreak == true true == true
parseIntoConfig( argv, config ) parseIntoConfig( argv, config ) config.shouldDebugBreak true
parseIntoConfig( argv, config ) parseIntoConfig( argv, config ) config.abortAfter == 1 1 == 1
parseIntoConfig( argv, config ) parseIntoConfig( argv, config ) config.abortAfter == 2 2 == 2
parseIntoConfigAndReturnError( argv, config ), Contains( "greater than zero" ) "Value after -x or --abortAfter must be greater than zero - while parsing: (-x, --abortx <no. failures>)" contains: "greater than zero"
parseIntoConfigAndReturnError( argv, config ), Contains( "-x" ) "Unable to convert oops to destination type - while parsing: (-x, --abortx <no. failures>)" contains: "-x"
parseIntoConfig( argv, config ) parseIntoConfig( argv, config ) config.noThrow == true true == true
parseIntoConfig( argv, config ) parseIntoConfig( argv, config ) config.noThrow == true true == true
parseIntoConfig( argv, config ) parseIntoConfig( argv, config ) config.outputFilename == "filename.ext" "filename.ext" == "filename.ext"
parseIntoConfig( argv, config ) parseIntoConfig( argv, config ) config.outputFilename == "filename.ext" "filename.ext" == "filename.ext"
parseIntoConfig( argv, config ) parseIntoConfig( argv, config ) config.abortAfter == 1 1 == 1 config.shouldDebugBreak true config.noThrow == true true == true
parseIntoConfig( argv, config ) parseIntoConfig( argv, config ) config.useColour == UseColour::Auto 0 == 0
parseIntoConfig( argv, config ) parseIntoConfig( argv, config ) config.useColour == UseColour::Auto 0 == 0
parseIntoConfig( argv, config ) parseIntoConfig( argv, config ) config.useColour == UseColour::Yes 1 == 1
parseIntoConfig( argv, config ) parseIntoConfig( argv, config ) config.useColour == UseColour::No 2 == 2
parseIntoConfig( argv, config ), Contains( "colour mode must be one of" ) parseIntoConfig( argv, config ), Contains( "colour mode must be one of" )
truthy(false) Hey, its truthy! current counter 0 i := 0 i < 10 0 < 10 current counter 1 i := 1 i < 10 1 < 10 current counter 2 i := 2 i < 10 2 < 10 current counter 3 i := 3 i < 10 3 < 10 current counter 4 i := 4 i < 10 4 < 10 current counter 5 i := 5 i < 10 5 < 10 current counter 6 i := 6 i < 10 6 < 10 current counter 7 i := 7 i < 10 7 < 10 current counter 8 i := 8 i < 10 8 < 10 current counter 9 i := 9 i < 10 9 < 10 current counter 10 i := 10 i < 10 10 < 10
before == 0 0 == 0
after > before 1 > 0
itDoesThis() true
itDoesThat() true
v.size() == 0 0 == 0
v.size() == 10 10 == 10 v.capacity() >= 10 10 >= 10
v.size() == 5 5 == 5 v.capacity() >= 10 10 >= 10
v.size() == 0 0 == 0
v.capacity() >= 10 10 >= 10 v.size() == 0 0 == 0
A string sent directly to stdout A string sent directly to stderr d == Approx( 1.23 ) 1.23 == Approx( 1.23 ) d != Approx( 1.22 ) 1.23 != Approx( 1.22 ) d != Approx( 1.24 ) 1.23 != Approx( 1.24 ) Approx( d ) == 1.23 Approx( 1.23 ) == 1.23 Approx( d ) != 1.22 Approx( 1.23 ) != 1.22 Approx( d ) != 1.24 Approx( 1.23 ) != 1.24 0 == Approx(0) 0 == Approx( 0.0 )
Write to std::cerr Write to std::clog Interleaved writes to error streams
Message from section one Message from section two
testStringForMatching(), StartsWith( "string" ) "this string contains 'abc' as a substring" starts with: "string" testStringForMatching(), Contains( "string" ) "this string contains 'abc' as a substring" contains: "string" testStringForMatching(), Contains( "abc" ) "this string contains 'abc' as a substring" contains: "abc" testStringForMatching(), StartsWith( "this" ) "this string contains 'abc' as a substring" starts with: "this" testStringForMatching(), EndsWith( "substring" ) "this string contains 'abc' as a substring" ends with: "substring" hello hello s1 == s2 "if ($b == 10) { $a = 20; }" == "if ($b == 10) { $a = 20; } "
what, Contains( "[@zzz]" ) "error: tag alias, "[@zzz]" already registered. First seen at file:2 Redefined at file:10 " contains: "[@zzz]" what, Contains( "file" ) "error: tag alias, "[@zzz]" already registered. First seen at file:2 Redefined at file:10 " contains: "file" what, Contains( "2" ) "error: tag alias, "[@zzz]" already registered. First seen at file:2 Redefined at file:10 " contains: "2" what, Contains( "10" ) "error: tag alias, "[@zzz]" already registered. First seen at file:2 Redefined at file:10 " contains: "10"
registry.add( "[no ampersat]", "", Catch::SourceLineInfo( "file", 3 ) ) registry.add( "[no ampersat]", "", Catch::SourceLineInfo( "file", 3 ) ) registry.add( "[the @ is not at the start]", "", Catch::SourceLineInfo( "file", 3 ) ) registry.add( "[the @ is not at the start]", "", Catch::SourceLineInfo( "file", 3 ) ) registry.add( "@no square bracket at start]", "", Catch::SourceLineInfo( "file", 3 ) ) registry.add( "@no square bracket at start]", "", Catch::SourceLineInfo( "file", 3 ) ) registry.add( "[@no square bracket at end", "", Catch::SourceLineInfo( "file", 3 ) ) registry.add( "[@no square bracket at end", "", Catch::SourceLineInfo( "file", 3 ) )
0x == bit30and31 3221225472 (0x) == 3221225472 Text( "hi there" ).toString() == "hi there" "hi there" == "hi there" Text( "hi there", narrow ).toString() == "hi\nthere" "hi there" == "hi there" 1 == 2 1 == 2 testCase.isOpen() true s1.isOpen() true
s1.isSuccessfullyCompleted() true testCase.isComplete() == false false == false ctx.completedCycle() true testCase.isSuccessfullyCompleted() true
testCase.isOpen() true s1.isOpen() true
s1.isComplete() true s1.isSuccessfullyCompleted() == false false == false testCase.isComplete() == false false == false ctx.completedCycle() true testCase.isSuccessfullyCompleted() == false false == false
testCase2.isOpen() true s1b.isOpen() == false false == false ctx.completedCycle() true testCase.isComplete() true testCase.isSuccessfullyCompleted() true
testCase.isOpen() true s1.isOpen() true
s1.isComplete() true s1.isSuccessfullyCompleted() == false false == false testCase.isComplete() == false false == false ctx.completedCycle() true testCase.isSuccessfullyCompleted() == false false == false
testCase2.isOpen() true s1b.isOpen() == false false == false s2.isOpen() true ctx.completedCycle() true testCase.isComplete() true testCase.isSuccessfullyCompleted() true
testCase.isOpen() true s1.isOpen() true
s2.isOpen() == false false == false testCase.isComplete() == false false == false
testCase2.isOpen() true s1b.isOpen() == false false == false s2b.isOpen() true ctx.completedCycle() == false false == false
ctx.completedCycle() true s2b.isSuccessfullyCompleted() true testCase2.isComplete() == false false == false testCase2.isSuccessfullyCompleted() true
testCase.isOpen() true s1.isOpen() true
s2.isOpen() == false false == false testCase.isComplete() == false false == false
testCase2.isOpen() true s1b.isOpen() == false false == false s2b.isOpen() true ctx.completedCycle() == false false == false
ctx.completedCycle() true s2b.isComplete() true s2b.isSuccessfullyCompleted() == false false == false testCase2.isSuccessfullyCompleted() == false false == false testCase3.isOpen() true s1c.isOpen() == false false == false s2c.isOpen() == false false == false testCase3.isSuccessfullyCompleted() true
testCase.isOpen() true s1.isOpen() true
s2.isOpen() true s2.isComplete() true s1.isComplete() == false false == false s1.isComplete() true testCase.isComplete() == false false == false testCase.isComplete() true
testCase.isOpen() true s1.isOpen() true
g1.isOpen() true g1.index() == 0 0 == 0 g1.isComplete() == false false == false s1.isComplete() == false false == false
s1.isComplete() == false false == false testCase.isSuccessfullyCompleted() == false false == false
testCase2.isOpen() true s1b.isOpen() true g1b.isOpen() true g1b.index() == 1 1 == 1 s1.isComplete() == false false == false s1b.isComplete() true g1b.isComplete() true testCase2.isComplete() true
testCase.isOpen() true s1.isOpen() true
g1.isOpen() true g1.index() == 0 0 == 0 g1.isComplete() == false false == false s1.isComplete() == false false == false
s2.isOpen() true s2.isComplete() true s1.isComplete() == false false == false testCase.isComplete() == false false == false
testCase2.isOpen() true s1b.isOpen() true g1b.isOpen() true g1b.index() == 1 1 == 1 s2b.isOpen() true s2b.isComplete() true g1b.isComplete() true s1b.isComplete() true testCase2.isComplete() true
testCase.isOpen() true s1.isOpen() true
g1.isOpen() true g1.index() == 0 0 == 0 g1.isComplete() == false false == false s1.isComplete() == false false == false
s2.isOpen() true s2.isComplete() true s2.isSuccessfullyCompleted() == false false == false s1.isComplete() == false false == false testCase.isComplete() == false false == false
testCase2.isOpen() true s1b.isOpen() true g1b.isOpen() true g1b.index() == 0 0 == 0 s2b.isOpen() == false false == false g1b.isComplete() == false false == false s1b.isComplete() == false false == false testCase2.isComplete() == false false == false testCase3.isOpen() true s1c.isOpen() true g1c.isOpen() true g1c.index() == 1 1 == 1 s2c.isOpen() true s2c.isComplete() true g1c.isComplete() true s1c.isComplete() true testCase3.isComplete() true
3.14 d == approx( 1.23 ) 1.23 == Approx( 1.23 ) d == approx( 1.22 ) 1.23 == Approx( 1.22 ) d == approx( 1.24 ) 1.23 == Approx( 1.24 ) d != approx( 1.25 ) 1.23 != Approx( 1.25 ) approx( d ) == 1.23 Approx( 1.23 ) == 1.23 approx( d ) == 1.22 Approx( 1.23 ) == 1.22 approx( d ) == 1.24 Approx( 1.23 ) == 1.24 approx( d ) != 1.25 Approx( 1.23 ) != 1.25
v, VectorContains( 1 ) { 1, 2, 3 } Contains: 1 v, VectorContains( 2 ) { 1, 2, 3 } Contains: 2
v, Contains( v2 ) { 1, 2, 3 } Contains: { 1, 2 } v, Contains( v2 ) { 1, 2, 3 } Contains: { 1, 2, 3 } v, Contains( empty) { 1, 2, 3 } Contains: { } empty, Contains( empty) { } Contains: { }
v, Equals( v ) { 1, 2, 3 } Equals: { 1, 2, 3 } empty, Equals( empty ) { } Equals: { } v, Equals( v2 ) { 1, 2, 3 } Equals: { 1, 2, 3 }
v, VectorContains( -1 ) { 1, 2, 3 } Contains: -1 empty, VectorContains( 1 ) { } Contains: 1
empty, Contains( v) { } Contains: { 1, 2, 3 } v, Contains( v2 ) { 1, 2, 3 } Contains: { 1, 2, 4 }
v, Equals( v2 ) { 1, 2, 3 } Equals: { 1, 2 } v2, Equals( v ) { 1, 2 } Equals: { 1, 2, 3 } empty, Equals( v ) { } Equals: { 1, 2, 3 } v, Equals( empty ) { 1, 2, 3 } Equals: { }
thisThrows(), std::domain_error thisThrows(), std::domain_error thisDoesntThrow() thisDoesntThrow() thisThrows() thisThrows() unexpected exception thisThrows() == 0 thisThrows() == 0 expected exception thisThrows() == 0 thisThrows() == 0 expected exception thisThrows() == 0 thisThrows() == 0 expected exception
unexpected exception
Uncomment the code in this test to check that it gives a sensible compiler error Uncomment the code in this test to check that it gives a sensible compiler error
encode( "normal string" ) == "normal string" "normal string" == "normal string"
encode( "" ) == "" "" == ""
encode( "smith & jones" ) == "smith &amp; jones" "smith &amp; jones" == "smith &amp; jones"
encode( "smith < jones" ) == "smith &lt; jones" "smith &lt; jones" == "smith &lt; jones"
encode( "smith > jones" ) == "smith > jones" "smith > jones" == "smith > jones" encode( "smith ]]> jones" ) == "smith ]]&gt; jones" "smith ]]&gt; jones" == "smith ]]&gt; jones"
encode( stringWithQuotes ) == stringWithQuotes "don't "quote" me on that" == "don't "quote" me on that" encode( stringWithQuotes, Catch::XmlEncode::ForAttributes ) == "don't &quot;quote&quot; me on that" "don't &quot;quote&quot; me on that" == "don't &quot;quote&quot; me on that"
encode( "[\x01]" ) == "[\\x01]" "[\x01]" == "[\x01]"
encode( "[\x7F]" ) == "[\\x7F]" "[\x7F]" == "[\x7F]"
x == 0 0 == 0 obj.prop != 0 0x != 0 flag true testCheckedElse( true ) true flag false testCheckedElse( false ) false flag true testCheckedIf( true ) true flag false testCheckedIf( false ) false unsigned_char_var == 1 1 == 1 unsigned_short_var == 1 1 == 1 unsigned_int_var == 1 1 == 1 unsigned_long_var == 1 1 == 1 long_var == unsigned_char_var 1 == 1 long_var == unsigned_short_var 1 == 1 long_var == unsigned_int_var 1 == 1 long_var == unsigned_long_var 1 == 1
spanner Previous info should not be seen
b > a 0 > 1
Testing if fib[0] (1) is even ( fib[i] % 2 ) == 0 1 == 0 Testing if fib[1] (1) is even ( fib[i] % 2 ) == 0 1 == 0 Testing if fib[2] (2) is even ( fib[i] % 2 ) == 0 0 == 0 Testing if fib[3] (3) is even ( fib[i] % 2 ) == 0 1 == 0 Testing if fib[4] (5) is even ( fib[i] % 2 ) == 0 1 == 0 Testing if fib[5] (8) is even ( fib[i] % 2 ) == 0 0 == 0 Testing if fib[6] (13) is even ( fib[i] % 2 ) == 0 1 == 0 Testing if fib[7] (21) is even ( fib[i] % 2 ) == 0 1 == 0
a == b 1 == 2
a != b 1 != 2
a < b 1 < 2
a != b 1 != 2 b != a 2 != 1
a != b 1 != 2
s == "7" "7" == "7" makeString( false ) != static_cast<char*>(0) "valid string" != {null string} makeString( true ) == static_cast<char*>(0) {null string} == {null string} Catch::toString( pair ) == "{ { 42, \"Arthur\" }, { \"Ford\", 24 } }" "{ { 42, "Arthur" }, { "Ford", 24 } }" == "{ { 42, "Arthur" }, { "Ford", 24 } }" p == 0 NULL == 0
a != b 1 != 2 b != a 2 != 1
a != b 1 != 2
replaceInPlace( letters, "b", "z" ) true letters == "azcdefcg" "azcdefcg" == "azcdefcg"
replaceInPlace( letters, "c", "z" ) true letters == "abzdefzg" "abzdefzg" == "abzdefzg"
replaceInPlace( letters, "a", "z" ) true letters == "zbcdefcg" "zbcdefcg" == "zbcdefcg"
replaceInPlace( letters, "g", "z" ) true letters == "abcdefcz" "abcdefcz" == "abcdefcz"
replaceInPlace( letters, letters, "replaced" ) true letters == "replaced" "replaced" == "replaced"
!(replaceInPlace( letters, "x", "z" )) !false letters == letters "abcdefcg" == "abcdefcg"
replaceInPlace( s, "'", "|'" ) true s == "didn|'t" "didn|'t" == "didn|'t"
3 false false hi i := 7 false false Catch::toString(value) == "{ 34, \"xyzzy\" }" "{ 34, "xyzzy" }" == "{ 34, "xyzzy" }" Catch::toString( value ) == "{ 34, \"xyzzy\" }" "{ 34, "xyzzy" }" == "{ 34, "xyzzy" }" Catch::toString( pr ) == "{ { \"green\", 55 } }" "{ { "green", 55 } }" == "{ { "green", 55 } }" std::string( "first" ) == "second" "first" == "second" result == "\"wide load\"" ""wide load"" == ""wide load"" result == "\"wide load\"" ""wide load"" == ""wide load"" result == "\"wide load\"" ""wide load"" == ""wide load"" result == "\"wide load\"" ""wide load"" == ""wide load"" Catch::toString( item ) == "StringMaker<has_maker>" "StringMaker<has_maker>" == "StringMaker<has_maker>" Catch::toString( item ) == "toString( has_maker_and_toString )" "toString( has_maker_and_toString )" == "toString( has_maker_and_toString )" Catch::toString( item ) == "toString( has_toString )" "toString( has_toString )" == "toString( has_toString )" Catch::toString( v ) == "{ StringMaker<has_maker> }" "{ StringMaker<has_maker> }" == "{ StringMaker<has_maker> }" Catch::toString(e0) == "E2{0}" "E2{0}" == "E2{0}" Catch::toString(e1) == "E2{1}" "E2{1}" == "E2{1}" Catch::toString(e0) == "0" "0" == "0" Catch::toString(e1) == "1" "1" == "1" Catch::toString(vv) == "{ }" "{ }" == "{ }" Catch::toString(vv) == "{ 42 }" "{ 42 }" == "{ 42 }" Catch::toString(vv) == "{ 42, 250 }" "{ 42, 250 }" == "{ 42, 250 }" Catch::toString(vv) == "{ }" "{ }" == "{ }" Catch::toString(vv) == "{ \"hello\" }" "{ "hello" }" == "{ "hello" }" Catch::toString(vv) == "{ \"hello\", \"world\" }" "{ "hello", "world" }" == "{ "hello", "world" }" v.size() == 5 5 == 5 v.capacity() >= 5 5 >= 5
v.size() == 10 10 == 10 v.capacity() >= 10 10 >= 10
v.size() == 5 5 == 5 v.capacity() >= 5 5 >= 5
v.size() == 0 0 == 0 v.capacity() >= 5 5 >= 5
v.capacity() == 0 0 == 0
v.size() == 5 5 == 5 v.capacity() >= 5 5 >= 5
v.size() == 5 5 == 5 v.capacity() >= 10 10 >= 10
v.size() == 5 5 == 5 v.capacity() >= 5 5 >= 5
v.size() == 5 5 == 5 v.capacity() >= 5 5 >= 5
catch-1.12.1/projects/SelfTest/ClassTests.cpp000066400000000000000000000023361325474075300210520ustar00rootroot00000000000000/* * Created by Phil on 09/11/2010. * Copyright 2010 Two Blue Cubes Ltd. All rights reserved. * * Distributed under the Boost Software License, Version 1.0. (See accompanying * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) */ #include "catch.hpp" namespace { class TestClass { std::string s; public: TestClass() : s( "hello" ) {} void succeedingCase() { REQUIRE( s == "hello" ); } void failingCase() { REQUIRE( s == "world" ); } }; } METHOD_AS_TEST_CASE( TestClass::succeedingCase, "A METHOD_AS_TEST_CASE based test run that succeeds", "[class]" ) METHOD_AS_TEST_CASE( TestClass::failingCase, "A METHOD_AS_TEST_CASE based test run that fails", "[.][class][failing]" ) struct Fixture { Fixture() : m_a( 1 ) {} int m_a; }; TEST_CASE_METHOD( Fixture, "A TEST_CASE_METHOD based test run that succeeds", "[class]" ) { REQUIRE( m_a == 1 ); } // We should be able to write our tests within a different namespace namespace Inner { TEST_CASE_METHOD( Fixture, "A TEST_CASE_METHOD based test run that fails", "[.][class][failing]" ) { REQUIRE( m_a == 2 ); } } catch-1.12.1/projects/SelfTest/CmdLineTests.cpp000066400000000000000000000247351325474075300213270ustar00rootroot00000000000000/* * Created by Phil on 13/5/2013. * Copyright 2014 Two Blue Cubes Ltd. All rights reserved. * * Distributed under the Boost Software License, Version 1.0. (See accompanying * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) */ #include "catch.hpp" #include "internal/catch_test_spec_parser.hpp" #ifdef __clang__ # pragma clang diagnostic ignored "-Wc++98-compat" #endif inline Catch::TestCase fakeTestCase( const char* name, const char* desc = "" ){ return Catch::makeTestCase( CATCH_NULL, "", name, desc, CATCH_INTERNAL_LINEINFO ); } TEST_CASE( "Parse test names and tags", "" ) { using Catch::parseTestSpec; using Catch::TestSpec; Catch::TestCase tcA = fakeTestCase( "a", "" ); Catch::TestCase tcB = fakeTestCase( "b", "[one][x]" ); Catch::TestCase tcC = fakeTestCase( "longer name with spaces", "[two][three][.][x]" ); Catch::TestCase tcD = fakeTestCase( "zlonger name with spacesz", "" ); SECTION( "Empty test spec should have no filters", "" ) { TestSpec spec; CHECK( spec.hasFilters() == false ); CHECK( spec.matches( tcA ) == false ); CHECK( spec.matches( tcB ) == false ); } SECTION( "Test spec from empty string should have no filters", "" ) { TestSpec spec = parseTestSpec( "" ); CHECK( spec.hasFilters() == false ); CHECK( spec.matches(tcA ) == false ); CHECK( spec.matches( tcB ) == false ); } SECTION( "Test spec from just a comma should have no filters", "" ) { TestSpec spec = parseTestSpec( "," ); CHECK( spec.hasFilters() == false ); CHECK( spec.matches( tcA ) == false ); CHECK( spec.matches( tcB ) == false ); } SECTION( "Test spec from name should have one filter", "" ) { TestSpec spec = parseTestSpec( "b" ); CHECK( spec.hasFilters() == true ); CHECK( spec.matches( tcA ) == false ); CHECK( spec.matches( tcB ) == true ); } SECTION( "Test spec from quoted name should have one filter", "" ) { TestSpec spec = parseTestSpec( "\"b\"" ); CHECK( spec.hasFilters() == true ); CHECK( spec.matches( tcA ) == false ); CHECK( spec.matches( tcB ) == true ); } SECTION( "Test spec from name should have one filter", "" ) { TestSpec spec = parseTestSpec( "b" ); CHECK( spec.hasFilters() == true ); CHECK( spec.matches( tcA ) == false ); CHECK( spec.matches( tcB ) == true ); CHECK( spec.matches( tcC ) == false ); } SECTION( "Wildcard at the start", "" ) { TestSpec spec = parseTestSpec( "*spaces" ); CHECK( spec.hasFilters() == true ); CHECK( spec.matches( tcA ) == false ); CHECK( spec.matches( tcB ) == false ); CHECK( spec.matches( tcC ) == true ); CHECK( spec.matches( tcD ) == false ); CHECK( parseTestSpec( "*a" ).matches( tcA ) == true ); } SECTION( "Wildcard at the end", "" ) { TestSpec spec = parseTestSpec( "long*" ); CHECK( spec.hasFilters() == true ); CHECK( spec.matches( tcA ) == false ); CHECK( spec.matches( tcB ) == false ); CHECK( spec.matches( tcC ) == true ); CHECK( spec.matches( tcD ) == false ); CHECK( parseTestSpec( "a*" ).matches( tcA ) == true ); } SECTION( "Wildcard at both ends", "" ) { TestSpec spec = parseTestSpec( "*name*" ); CHECK( spec.hasFilters() == true ); CHECK( spec.matches( tcA ) == false ); CHECK( spec.matches( tcB ) == false ); CHECK( spec.matches( tcC ) == true ); CHECK( spec.matches( tcD ) == true ); CHECK( parseTestSpec( "*a*" ).matches( tcA ) == true ); } SECTION( "Redundant wildcard at the start", "" ) { TestSpec spec = parseTestSpec( "*a" ); CHECK( spec.hasFilters() == true ); CHECK( spec.matches( tcA ) == true ); CHECK( spec.matches( tcB ) == false ); } SECTION( "Redundant wildcard at the end", "" ) { TestSpec spec = parseTestSpec( "a*" ); CHECK( spec.hasFilters() == true ); CHECK( spec.matches( tcA ) == true ); CHECK( spec.matches( tcB ) == false ); } SECTION( "Redundant wildcard at both ends", "" ) { TestSpec spec = parseTestSpec( "*a*" ); CHECK( spec.hasFilters() == true ); CHECK( spec.matches( tcA ) == true ); CHECK( spec.matches( tcB ) == false ); } SECTION( "Wildcard at both ends, redundant at start", "" ) { TestSpec spec = parseTestSpec( "*longer*" ); CHECK( spec.hasFilters() == true ); CHECK( spec.matches( tcA ) == false ); CHECK( spec.matches( tcB ) == false ); CHECK( spec.matches( tcC ) == true ); CHECK( spec.matches( tcD ) == true ); } SECTION( "Just wildcard", "" ) { TestSpec spec = parseTestSpec( "*" ); CHECK( spec.hasFilters() == true ); CHECK( spec.matches( tcA ) == true ); CHECK( spec.matches( tcB ) == true ); CHECK( spec.matches( tcC ) == true ); CHECK( spec.matches( tcD ) == true ); } SECTION( "Single tag", "" ) { TestSpec spec = parseTestSpec( "[one]" ); CHECK( spec.hasFilters() == true ); CHECK( spec.matches( tcA ) == false ); CHECK( spec.matches( tcB ) == true ); CHECK( spec.matches( tcC ) == false ); } SECTION( "Single tag, two matches", "" ) { TestSpec spec = parseTestSpec( "[x]" ); CHECK( spec.hasFilters() == true ); CHECK( spec.matches( tcA ) == false ); CHECK( spec.matches( tcB ) == true ); CHECK( spec.matches( tcC ) == true ); } SECTION( "Two tags", "" ) { TestSpec spec = parseTestSpec( "[two][x]" ); CHECK( spec.hasFilters() == true ); CHECK( spec.matches( tcA ) == false ); CHECK( spec.matches( tcB ) == false ); CHECK( spec.matches( tcC ) == true ); } SECTION( "Two tags, spare separated", "" ) { TestSpec spec = parseTestSpec( "[two] [x]" ); CHECK( spec.hasFilters() == true ); CHECK( spec.matches( tcA ) == false ); CHECK( spec.matches( tcB ) == false ); CHECK( spec.matches( tcC ) == true ); } SECTION( "Wildcarded name and tag", "" ) { TestSpec spec = parseTestSpec( "*name*[x]" ); CHECK( spec.hasFilters() == true ); CHECK( spec.matches( tcA ) == false ); CHECK( spec.matches( tcB ) == false ); CHECK( spec.matches( tcC ) == true ); CHECK( spec.matches( tcD ) == false ); } SECTION( "Single tag exclusion", "" ) { TestSpec spec = parseTestSpec( "~[one]" ); CHECK( spec.hasFilters() == true ); CHECK( spec.matches( tcA ) == true ); CHECK( spec.matches( tcB ) == false ); CHECK( spec.matches( tcC ) == true ); } SECTION( "One tag exclusion and one tag inclusion", "" ) { TestSpec spec = parseTestSpec( "~[two][x]" ); CHECK( spec.hasFilters() == true ); CHECK( spec.matches( tcA ) == false ); CHECK( spec.matches( tcB ) == true ); CHECK( spec.matches( tcC ) == false ); } SECTION( "One tag exclusion and one wldcarded name inclusion", "" ) { TestSpec spec = parseTestSpec( "~[two]*name*" ); CHECK( spec.hasFilters() == true ); CHECK( spec.matches( tcA ) == false ); CHECK( spec.matches( tcB ) == false ); CHECK( spec.matches( tcC ) == false ); CHECK( spec.matches( tcD ) == true ); } SECTION( "One tag exclusion, using exclude:, and one wldcarded name inclusion", "" ) { TestSpec spec = parseTestSpec( "exclude:[two]*name*" ); CHECK( spec.hasFilters() == true ); CHECK( spec.matches( tcA ) == false ); CHECK( spec.matches( tcB ) == false ); CHECK( spec.matches( tcC ) == false ); CHECK( spec.matches( tcD ) == true ); } SECTION( "name exclusion", "" ) { TestSpec spec = parseTestSpec( "~b" ); CHECK( spec.hasFilters() == true ); CHECK( spec.matches( tcA ) == true ); CHECK( spec.matches( tcB ) == false ); CHECK( spec.matches( tcC ) == true ); CHECK( spec.matches( tcD ) == true ); } SECTION( "wildcarded name exclusion", "" ) { TestSpec spec = parseTestSpec( "~*name*" ); CHECK( spec.hasFilters() == true ); CHECK( spec.matches( tcA ) == true ); CHECK( spec.matches( tcB ) == true ); CHECK( spec.matches( tcC ) == false ); CHECK( spec.matches( tcD ) == false ); } SECTION( "wildcarded name exclusion with tag inclusion", "" ) { TestSpec spec = parseTestSpec( "~*name*,[three]" ); CHECK( spec.hasFilters() == true ); CHECK( spec.matches( tcA ) == true ); CHECK( spec.matches( tcB ) == true ); CHECK( spec.matches( tcC ) == true ); CHECK( spec.matches( tcD ) == false ); } SECTION( "wildcarded name exclusion, using exclude:, with tag inclusion", "" ) { TestSpec spec = parseTestSpec( "exclude:*name*,[three]" ); CHECK( spec.hasFilters() == true ); CHECK( spec.matches( tcA ) == true ); CHECK( spec.matches( tcB ) == true ); CHECK( spec.matches( tcC ) == true ); CHECK( spec.matches( tcD ) == false ); } SECTION( "two wildcarded names", "" ) { TestSpec spec = parseTestSpec( "\"longer*\"\"*spaces\"" ); CHECK( spec.hasFilters() == true ); CHECK( spec.matches( tcA ) == false ); CHECK( spec.matches( tcB ) == false ); CHECK( spec.matches( tcC ) == true ); CHECK( spec.matches( tcD ) == false ); } SECTION( "empty tag", "" ) { TestSpec spec = parseTestSpec( "[]" ); CHECK( spec.hasFilters() == false ); CHECK( spec.matches( tcA ) == false ); CHECK( spec.matches( tcB ) == false ); CHECK( spec.matches( tcC ) == false ); CHECK( spec.matches( tcD ) == false ); } SECTION( "empty quoted name", "" ) { TestSpec spec = parseTestSpec( "\"\"" ); CHECK( spec.hasFilters() == false ); CHECK( spec.matches( tcA ) == false ); CHECK( spec.matches( tcB ) == false ); CHECK( spec.matches( tcC ) == false ); CHECK( spec.matches( tcD ) == false ); } SECTION( "quoted string followed by tag exclusion", "" ) { TestSpec spec = parseTestSpec( "\"*name*\"~[.]" ); CHECK( spec.hasFilters() == true ); CHECK( spec.matches( tcA ) == false ); CHECK( spec.matches( tcB ) == false ); CHECK( spec.matches( tcC ) == false ); CHECK( spec.matches( tcD ) == true ); } } catch-1.12.1/projects/SelfTest/CompilationTests.cpp000066400000000000000000000031231325474075300222560ustar00rootroot00000000000000/* * Created by Martin on 17/02/2017. * * Distributed under the Boost Software License, Version 1.0. (See accompanying * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) */ #include "catch.hpp" // This is a minimal example for an issue we have found in 1.7.0 struct foo { int i; }; template bool operator==(const T& val, foo f){ return val == f.i; } TEST_CASE("#809") { foo f; f.i = 42; REQUIRE(42 == f); } // ------------------------------------------------------------------ // Changes to REQUIRE_THROWS_AS made it stop working in a template in // an unfixable way (as long as C++03 compatibility is being kept). // To prevent these from happening in the future, this needs to compile void throws_int(bool b) { if (b) { throw 1; } } template bool templated_tests(T t) { int a = 3; REQUIRE(a == t); CHECK(a == t); REQUIRE_THROWS(throws_int(true)); CHECK_THROWS_AS(throws_int(true), const int&); REQUIRE_NOTHROW(throws_int(false)); REQUIRE_THAT("aaa", Catch::EndsWith("aaa")); return true; } TEST_CASE("#833") { REQUIRE(templated_tests(3)); } // Test containing example where original stream insertable check breaks compilation #if defined (CATCH_CONFIG_CPP11_STREAM_INSERTABLE_CHECK) namespace { struct A {}; std::ostream& operator<< (std::ostream &o, const A &) { return o << 0; } struct B : private A { bool operator== (int) const { return true; } }; B f (); std::ostream g (); } TEST_CASE( "#872" ) { B x; REQUIRE (x == 4); } #endif catch-1.12.1/projects/SelfTest/ConditionTests.cpp000066400000000000000000000212201325474075300217240ustar00rootroot00000000000000/* * Created by Phil on 08/11/2010. * Copyright 2010 Two Blue Cubes Ltd. All rights reserved. * * Distributed under the Boost Software License, Version 1.0. (See accompanying * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) */ #ifdef __clang__ # pragma clang diagnostic ignored "-Wpadded" # pragma clang diagnostic ignored "-Wc++98-compat" #endif #include "catch.hpp" #include #include struct TestData { TestData() : int_seven( 7 ), str_hello( "hello" ), float_nine_point_one( 9.1f ), double_pi( 3.1415926535 ) {} int int_seven; std::string str_hello; float float_nine_point_one; double double_pi; }; struct TestDef { TestDef& operator + ( const std::string& ) { return *this; } TestDef& operator[]( const std::string& ) { return *this; } }; // The "failing" tests all use the CHECK macro, which continues if the specific test fails. // This allows us to see all results, even if an earlier check fails // Equality tests TEST_CASE( "Equality checks that should succeed", "" ) { TestDef td; td + "hello" + "hello"; TestData data; REQUIRE( data.int_seven == 7 ); REQUIRE( data.float_nine_point_one == Approx( 9.1f ) ); REQUIRE( data.double_pi == Approx( 3.1415926535 ) ); REQUIRE( data.str_hello == "hello" ); REQUIRE( "hello" == data.str_hello ); REQUIRE( data.str_hello.size() == 5 ); double x = 1.1 + 0.1 + 0.1; REQUIRE( x == Approx( 1.3 ) ); } TEST_CASE( "Equality checks that should fail", "[.][failing][!mayfail]" ) { TestData data; CHECK( data.int_seven == 6 ); CHECK( data.int_seven == 8 ); CHECK( data.int_seven == 0 ); CHECK( data.float_nine_point_one == Approx( 9.11f ) ); CHECK( data.float_nine_point_one == Approx( 9.0f ) ); CHECK( data.float_nine_point_one == Approx( 1 ) ); CHECK( data.float_nine_point_one == Approx( 0 ) ); CHECK( data.double_pi == Approx( 3.1415 ) ); CHECK( data.str_hello == "goodbye" ); CHECK( data.str_hello == "hell" ); CHECK( data.str_hello == "hello1" ); CHECK( data.str_hello.size() == 6 ); double x = 1.1 + 0.1 + 0.1; CHECK( x == Approx( 1.301 ) ); } TEST_CASE( "Inequality checks that should succeed", "" ) { TestData data; REQUIRE( data.int_seven != 6 ); REQUIRE( data.int_seven != 8 ); REQUIRE( data.float_nine_point_one != Approx( 9.11f ) ); REQUIRE( data.float_nine_point_one != Approx( 9.0f ) ); REQUIRE( data.float_nine_point_one != Approx( 1 ) ); REQUIRE( data.float_nine_point_one != Approx( 0 ) ); REQUIRE( data.double_pi != Approx( 3.1415 ) ); REQUIRE( data.str_hello != "goodbye" ); REQUIRE( data.str_hello != "hell" ); REQUIRE( data.str_hello != "hello1" ); REQUIRE( data.str_hello.size() != 6 ); } TEST_CASE( "Inequality checks that should fail", "[.][failing][!shouldfail]" ) { TestData data; CHECK( data.int_seven != 7 ); CHECK( data.float_nine_point_one != Approx( 9.1f ) ); CHECK( data.double_pi != Approx( 3.1415926535 ) ); CHECK( data.str_hello != "hello" ); CHECK( data.str_hello.size() != 5 ); } // Ordering comparison tests TEST_CASE( "Ordering comparison checks that should succeed", "" ) { TestData data; REQUIRE( data.int_seven < 8 ); REQUIRE( data.int_seven > 6 ); REQUIRE( data.int_seven > 0 ); REQUIRE( data.int_seven > -1 ); REQUIRE( data.int_seven >= 7 ); REQUIRE( data.int_seven >= 6 ); REQUIRE( data.int_seven <= 7 ); REQUIRE( data.int_seven <= 8 ); REQUIRE( data.float_nine_point_one > 9 ); REQUIRE( data.float_nine_point_one < 10 ); REQUIRE( data.float_nine_point_one < 9.2 ); REQUIRE( data.str_hello <= "hello" ); REQUIRE( data.str_hello >= "hello" ); REQUIRE( data.str_hello < "hellp" ); REQUIRE( data.str_hello < "zebra" ); REQUIRE( data.str_hello > "hellm" ); REQUIRE( data.str_hello > "a" ); } TEST_CASE( "Ordering comparison checks that should fail", "[.][failing]" ) { TestData data; CHECK( data.int_seven > 7 ); CHECK( data.int_seven < 7 ); CHECK( data.int_seven > 8 ); CHECK( data.int_seven < 6 ); CHECK( data.int_seven < 0 ); CHECK( data.int_seven < -1 ); CHECK( data.int_seven >= 8 ); CHECK( data.int_seven <= 6 ); CHECK( data.float_nine_point_one < 9 ); CHECK( data.float_nine_point_one > 10 ); CHECK( data.float_nine_point_one > 9.2 ); CHECK( data.str_hello > "hello" ); CHECK( data.str_hello < "hello" ); CHECK( data.str_hello > "hellp" ); CHECK( data.str_hello > "z" ); CHECK( data.str_hello < "hellm" ); CHECK( data.str_hello < "a" ); CHECK( data.str_hello >= "z" ); CHECK( data.str_hello <= "a" ); } // Comparisons with int literals TEST_CASE( "Comparisons with int literals don't warn when mixing signed/ unsigned", "" ) { int i = 1; unsigned int ui = 2; long l = 3; unsigned long ul = 4; char c = 5; unsigned char uc = 6; REQUIRE( i == 1 ); REQUIRE( ui == 2 ); REQUIRE( l == 3 ); REQUIRE( ul == 4 ); REQUIRE( c == 5 ); REQUIRE( uc == 6 ); REQUIRE( 1 == i ); REQUIRE( 2 == ui ); REQUIRE( 3 == l ); REQUIRE( 4 == ul ); REQUIRE( 5 == c ); REQUIRE( 6 == uc ); REQUIRE( (std::numeric_limits::max)() > ul ); } // Disable warnings about sign conversions for the next two tests // (as we are deliberately invoking them) // - Currently only disabled for GCC/ LLVM. Should add VC++ too #ifdef __GNUC__ #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wsign-compare" #pragma GCC diagnostic ignored "-Wsign-conversion" #endif #ifdef _MSC_VER #pragma warning(disable:4389) // '==' : signed/unsigned mismatch #endif TEST_CASE( "comparisons between int variables", "" ) { long long_var = 1L; unsigned char unsigned_char_var = 1; unsigned short unsigned_short_var = 1; unsigned int unsigned_int_var = 1; unsigned long unsigned_long_var = 1L; REQUIRE( long_var == unsigned_char_var ); REQUIRE( long_var == unsigned_short_var ); REQUIRE( long_var == unsigned_int_var ); REQUIRE( long_var == unsigned_long_var ); } TEST_CASE( "comparisons between const int variables", "" ) { const unsigned char unsigned_char_var = 1; const unsigned short unsigned_short_var = 1; const unsigned int unsigned_int_var = 1; const unsigned long unsigned_long_var = 1L; REQUIRE( unsigned_char_var == 1 ); REQUIRE( unsigned_short_var == 1 ); REQUIRE( unsigned_int_var == 1 ); REQUIRE( unsigned_long_var == 1 ); } TEST_CASE( "Comparisons between unsigned ints and negative signed ints match c++ standard behaviour", "" ) { CHECK( ( -1 > 2u ) ); CHECK( -1 > 2u ); CHECK( ( 2u < -1 ) ); CHECK( 2u < -1 ); const int minInt = (std::numeric_limits::min)(); CHECK( ( minInt > 2u ) ); CHECK( minInt > 2u ); } TEST_CASE( "Comparisons between ints where one side is computed", "" ) { CHECK( 54 == 6*9 ); } #ifdef __GNUC__ #pragma GCC diagnostic pop #endif inline const char* returnsConstNull(){ return CATCH_NULL; } inline char* returnsNull(){ return CATCH_NULL; } TEST_CASE( "Pointers can be compared to null", "" ) { TestData* p = CATCH_NULL; TestData* pNULL = CATCH_NULL; REQUIRE( p == CATCH_NULL ); REQUIRE( p == pNULL ); TestData data; p = &data; REQUIRE( p != CATCH_NULL ); const TestData* cp = p; REQUIRE( cp != CATCH_NULL ); const TestData* const cpc = p; REQUIRE( cpc != CATCH_NULL ); REQUIRE( returnsNull() == CATCH_NULL ); REQUIRE( returnsConstNull() == CATCH_NULL ); REQUIRE( CATCH_NULL != p ); } // Not (!) tests // The problem with the ! operator is that it has right-to-left associativity. // This means we can't isolate it when we decompose. The simple REQUIRE( !false ) form, therefore, // cannot have the operand value extracted. The test will work correctly, and the situation // is detected and a warning issued. // An alternative form of the macros (CHECK_FALSE and REQUIRE_FALSE) can be used instead to capture // the operand value. TEST_CASE( "'Not' checks that should succeed", "" ) { bool falseValue = false; REQUIRE( false == false ); REQUIRE( true == true ); REQUIRE( !false ); REQUIRE_FALSE( false ); REQUIRE( !falseValue ); REQUIRE_FALSE( falseValue ); REQUIRE( !(1 == 2) ); REQUIRE_FALSE( 1 == 2 ); } TEST_CASE( "'Not' checks that should fail", "[.][failing]" ) { bool trueValue = true; CHECK( false != false ); CHECK( true != true ); CHECK( !true ); CHECK_FALSE( true ); CHECK( !trueValue ); CHECK_FALSE( trueValue ); CHECK( !(1 == 1) ); CHECK_FALSE( 1 == 1 ); } catch-1.12.1/projects/SelfTest/DecompositionTests.cpp000066400000000000000000000012251325474075300226150ustar00rootroot00000000000000/* * Created by Martin on 27/5/2017. * Copyright 2017 Two Blue Cubes Ltd. All rights reserved. * * Distributed under the Boost Software License, Version 1.0. (See accompanying * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) */ #include struct truthy { truthy(bool b):m_value(b){} operator bool() const { return false; } bool m_value; }; std::ostream& operator<<(std::ostream& o, truthy) { o << "Hey, its truthy!"; return o; } #include "catch.hpp" TEST_CASE( "Reconstruction should be based on stringification: #914" , "[Decomposition][failing][.]") { CHECK(truthy(false)); } catch-1.12.1/projects/SelfTest/EnumToString.cpp000066400000000000000000000044721325474075300213630ustar00rootroot00000000000000#include "catch.hpp" /* TODO: maybe ought to check that user-provided specialisations of Catch::toString also do the right thing */ // Enum without user-provided stream operator enum Enum1 { Enum1Value0, Enum1Value1 }; TEST_CASE( "toString(enum)", "[toString][enum]" ) { Enum1 e0 = Enum1Value0; CHECK( Catch::toString(e0) == "0" ); Enum1 e1 = Enum1Value1; CHECK( Catch::toString(e1) == "1" ); } // Enum with user-provided stream operator enum Enum2 { Enum2Value0, Enum2Value1 }; inline std::ostream& operator<<( std::ostream& os, Enum2 v ) { return os << "E2{" << static_cast(v) << "}"; } TEST_CASE( "toString(enum w/operator<<)", "[toString][enum]" ) { Enum2 e0 = Enum2Value0; CHECK( Catch::toString(e0) == "E2{0}" ); Enum2 e1 = Enum2Value1; CHECK( Catch::toString(e1) == "E2{1}" ); } #if defined(CATCH_CPP11_OR_GREATER) #ifdef __clang__ #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wc++98-compat" #endif // Enum class without user-provided stream operator enum class EnumClass1 { EnumClass1Value0, EnumClass1Value1 }; TEST_CASE( "toString(enum class)", "[toString][enum][enumClass][c++11][.]" ) { EnumClass1 e0 = EnumClass1::EnumClass1Value0; CHECK( Catch::toString(e0) == "0" ); EnumClass1 e1 = EnumClass1::EnumClass1Value1; CHECK( Catch::toString(e1) == "1" ); } // Enum class with user-provided stream operator enum class EnumClass2 : short { EnumClass2Value0, EnumClass2Value1 }; inline std::ostream& operator<<( std::ostream& os, EnumClass2 e2 ) { switch( static_cast( e2 ) ) { case static_cast( EnumClass2::EnumClass2Value0 ): return os << "E2/V0"; case static_cast( EnumClass2::EnumClass2Value1 ): return os << "E2/V1"; default: return os << "Unknown enum value " << static_cast( e2 ); } } TEST_CASE( "toString(enum class w/operator<<)", "[toString][enum][enumClass][c++11][.]" ) { EnumClass2 e0 = EnumClass2::EnumClass2Value0; CHECK( Catch::toString(e0) == "E2/V0" ); EnumClass2 e1 = EnumClass2::EnumClass2Value1; CHECK( Catch::toString(e1) == "E2/V1" ); EnumClass2 e3 = static_cast(10); CHECK( Catch::toString(e3) == "Unknown enum value 10" ); } #ifdef __clang__ #pragma clang diagnostic pop #endif #endif // CATCH_CPP11_OR_GREATER catch-1.12.1/projects/SelfTest/ExceptionTests.cpp000066400000000000000000000135031325474075300217410ustar00rootroot00000000000000/* * Created by Phil on 09/11/2010. * Copyright 2010 Two Blue Cubes Ltd. All rights reserved. * * Distributed under the Boost Software License, Version 1.0. (See accompanying * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) */ #include "catch.hpp" #include #include #ifdef _MSC_VER #pragma warning(disable:4702) // Unreachable code -- MSVC 19 (VS 2015) sees right through the indirection #endif namespace { inline int thisThrows() { if( Catch::alwaysTrue() ) throw std::domain_error( "expected exception" ); return 1; } int thisDoesntThrow() { return 0; } } TEST_CASE( "When checked exceptions are thrown they can be expected or unexpected", "[!throws]" ) { REQUIRE_THROWS_AS( thisThrows(), std::domain_error ); REQUIRE_NOTHROW( thisDoesntThrow() ); REQUIRE_THROWS( thisThrows() ); } TEST_CASE( "Expected exceptions that don't throw or unexpected exceptions fail the test", "[.][failing][!throws]" ) { CHECK_THROWS_AS( thisThrows(), std::string ); CHECK_THROWS_AS( thisDoesntThrow(), std::domain_error ); CHECK_NOTHROW( thisThrows() ); } TEST_CASE( "When unchecked exceptions are thrown directly they are always failures", "[.][failing][!throws]" ) { if( Catch::alwaysTrue() ) throw std::domain_error( "unexpected exception" ); } TEST_CASE( "An unchecked exception reports the line of the last assertion", "[.][failing][!throws]" ) { CHECK( 1 == 1 ); if( Catch::alwaysTrue() ) throw std::domain_error( "unexpected exception" ); } TEST_CASE( "When unchecked exceptions are thrown from sections they are always failures", "[.][failing][!throws]" ) { SECTION( "section name", "" ) { if( Catch::alwaysTrue() ) throw std::domain_error( "unexpected exception" ); } } TEST_CASE( "When unchecked exceptions are thrown from functions they are always failures", "[.][failing][!throws]" ) { CHECK( thisThrows() == 0 ); } TEST_CASE( "When unchecked exceptions are thrown during a REQUIRE the test should abort fail", "[.][failing][!throws]" ) { REQUIRE( thisThrows() == 0 ); FAIL( "This should never happen" ); } TEST_CASE( "When unchecked exceptions are thrown during a CHECK the test should continue", "[.][failing][!throws]" ) { try { CHECK(thisThrows() == 0); } catch(...) { FAIL( "This should never happen" ); } } TEST_CASE( "When unchecked exceptions are thrown, but caught, they do not affect the test", "[!throws]" ) { try { throw std::domain_error( "unexpected exception" ); } catch(...) { } } class CustomException { public: CustomException( const std::string& msg ) : m_msg( msg ) {} std::string getMessage() const { return m_msg; } private: std::string m_msg; }; class CustomStdException : public std::exception { public: CustomStdException( const std::string& msg ) : m_msg( msg ) {} ~CustomStdException() CATCH_NOEXCEPT {} std::string getMessage() const { return m_msg; } private: std::string m_msg; }; CATCH_TRANSLATE_EXCEPTION( CustomException& ex ) { return ex.getMessage(); } CATCH_TRANSLATE_EXCEPTION( CustomStdException& ex ) { return ex.getMessage(); } CATCH_TRANSLATE_EXCEPTION( double& ex ) { return Catch::toString( ex ); } TEST_CASE("Non-std exceptions can be translated", "[.][failing][!throws]" ) { if( Catch::alwaysTrue() ) throw CustomException( "custom exception" ); } TEST_CASE("Custom std-exceptions can be custom translated", "[.][failing][!throws]" ) { if( Catch::alwaysTrue() ) throw CustomException( "custom std exception" ); } inline void throwCustom() { if( Catch::alwaysTrue() ) throw CustomException( "custom exception - not std" ); } TEST_CASE( "Custom exceptions can be translated when testing for nothrow", "[.][failing][!throws]" ) { REQUIRE_NOTHROW( throwCustom() ); } TEST_CASE( "Custom exceptions can be translated when testing for throwing as something else", "[.][failing][!throws]" ) { REQUIRE_THROWS_AS( throwCustom(), std::exception ); } TEST_CASE( "Unexpected exceptions can be translated", "[.][failing][!throws]" ) { if( Catch::alwaysTrue() ) throw double( 3.14 ); } inline int thisFunctionNotImplemented( int ) { CATCH_NOT_IMPLEMENTED; } TEST_CASE( "NotImplemented exception", "[!throws]" ) { REQUIRE_THROWS( thisFunctionNotImplemented( 7 ) ); } TEST_CASE( "Exception messages can be tested for", "[!throws]" ) { using namespace Catch::Matchers; SECTION( "exact match" ) REQUIRE_THROWS_WITH( thisThrows(), "expected exception" ); SECTION( "different case" ) REQUIRE_THROWS_WITH( thisThrows(), Equals( "expecteD Exception", Catch::CaseSensitive::No ) ); SECTION( "wildcarded" ) { REQUIRE_THROWS_WITH( thisThrows(), StartsWith( "expected" ) ); REQUIRE_THROWS_WITH( thisThrows(), EndsWith( "exception" ) ); REQUIRE_THROWS_WITH( thisThrows(), Contains( "except" ) ); REQUIRE_THROWS_WITH( thisThrows(), Contains( "exCept", Catch::CaseSensitive::No ) ); } } TEST_CASE( "Mismatching exception messages failing the test", "[.][failing][!throws]" ) { REQUIRE_THROWS_WITH( thisThrows(), "expected exception" ); REQUIRE_THROWS_WITH( thisThrows(), "should fail" ); REQUIRE_THROWS_WITH( thisThrows(), "expected exception" ); } TEST_CASE( "#748 - captures with unexpected exceptions", "[!shouldfail][!throws]" ) { int answer = 42; CAPTURE( answer ); // the message should be printed on the first two sections but not on the third SECTION( "outside assertions" ) { thisThrows(); } SECTION( "inside REQUIRE_NOTHROW" ) { REQUIRE_NOTHROW( thisThrows() ); } SECTION( "inside REQUIRE_THROWS" ) { REQUIRE_THROWS( thisThrows() ); } } catch-1.12.1/projects/SelfTest/GeneratorTests.cpp000066400000000000000000000021421325474075300217260ustar00rootroot00000000000000/* * Created by Phil on 28/01/2011. * Copyright 2011 Two Blue Cubes Ltd. All rights reserved. * * Distributed under the Boost Software License, Version 1.0. (See accompanying * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) */ // This define means we have to prefix all the CATCH macros with CATCH_ // We're using it here to test it out #define CATCH_CONFIG_PREFIX_ALL #include "catch.hpp" inline int multiply( int a, int b ) { return a*b; } CATCH_TEST_CASE( "Generators over two ranges", "[generators]" ) { using namespace Catch::Generators; int i = CATCH_GENERATE( between( 1, 5 ).then( values( 15, 20, 21 ).then( 36 ) ) ); int j = CATCH_GENERATE( between( 100, 107 ) ); CATCH_REQUIRE( multiply( i, 2 ) == i*2 ); CATCH_REQUIRE( multiply( j, 2 ) == j*2 ); } struct IntPair { int first, second; }; CATCH_TEST_CASE( "Generator over a range of pairs", "[generators]" ) { using namespace Catch::Generators; IntPair p[] = { { 0, 1 }, { 2, 3 } }; IntPair* i = CATCH_GENERATE( between( p, &p[1] ) ); CATCH_REQUIRE( i->first == i->second-1 ); } catch-1.12.1/projects/SelfTest/MatchersTests.cpp000066400000000000000000000120031325474075300215430ustar00rootroot00000000000000/* * Created by Phil on 21/02/2017. * Copyright 2017 Two Blue Cubes Ltd. All rights reserved. * * Distributed under the Boost Software License, Version 1.0. (See accompanying * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) */ #include "catch.hpp" inline const char* testStringForMatching() { return "this string contains 'abc' as a substring"; } inline const char* testStringForMatching2() { return "some completely different text that contains one common word"; } using namespace Catch::Matchers; TEST_CASE("String matchers", "[matchers]" ) { REQUIRE_THAT( testStringForMatching(), Contains( "string" ) ); CHECK_THAT( testStringForMatching(), Contains( "abc" ) ); CHECK_THAT( testStringForMatching(), StartsWith( "this" ) ); CHECK_THAT( testStringForMatching(), EndsWith( "substring" ) ); } TEST_CASE("Contains string matcher", "[.][failing][matchers]") { CHECK_THAT( testStringForMatching(), Contains( "not there" ) ); } TEST_CASE("StartsWith string matcher", "[.][failing][matchers]") { CHECK_THAT( testStringForMatching(), StartsWith( "string" ) ); } TEST_CASE("EndsWith string matcher", "[.][failing][matchers]") { CHECK_THAT( testStringForMatching(), EndsWith( "this" ) ); } TEST_CASE("Equals string matcher", "[.][failing][matchers]") { CHECK_THAT( testStringForMatching(), Equals( "something else" ) ); } TEST_CASE("AllOf matcher", "[matchers]") { CHECK_THAT( testStringForMatching(), AllOf( Catch::Contains( "string" ), Catch::Contains( "abc" ) ) ); } TEST_CASE("AnyOf matcher", "[matchers]") { CHECK_THAT( testStringForMatching(), AnyOf( Catch::Contains( "string" ), Catch::Contains( "not there" ) ) ); CHECK_THAT( testStringForMatching(), AnyOf( Catch::Contains( "not there" ), Catch::Contains( "string" ) ) ); } TEST_CASE("Equals", "[matchers]") { CHECK_THAT( testStringForMatching(), Equals( "this string contains 'abc' as a substring" ) ); } TEST_CASE("Matchers can be (AllOf) composed with the && operator", "[matchers][operators][operator&&]") { CHECK_THAT( testStringForMatching(), Contains( "string" ) && Contains( "abc" ) && Contains( "substring" ) && Contains( "contains" ) ); } TEST_CASE("Matchers can be (AnyOf) composed with the || operator", "[matchers][operators][operator||]") { CHECK_THAT( testStringForMatching(), Contains( "string" ) || Contains( "different" ) || Contains( "random" ) ); CHECK_THAT( testStringForMatching2(), Contains( "string" ) || Contains( "different" ) || Contains( "random" ) ); } TEST_CASE("Matchers can be composed with both && and ||", "[matchers][operators][operator||][operator&&]") { CHECK_THAT( testStringForMatching(), ( Contains( "string" ) || Contains( "different" ) ) && Contains( "substring" ) ); } TEST_CASE("Matchers can be composed with both && and || - failing", "[matchers][operators][operator||][operator&&][.failing]") { CHECK_THAT( testStringForMatching(), ( Contains( "string" ) || Contains( "different" ) ) && Contains( "random" ) ); } TEST_CASE("Matchers can be negated (Not) with the ! operator", "[matchers][operators][not]") { CHECK_THAT( testStringForMatching(), !Contains( "different" ) ); } TEST_CASE("Matchers can be negated (Not) with the ! operator - failing", "[matchers][operators][not][.failing]") { CHECK_THAT( testStringForMatching(), !Contains( "substring" ) ); } TEST_CASE( "Vector matchers", "[matchers][vector]" ) { std::vector v; v.push_back( 1 ); v.push_back( 2 ); v.push_back( 3 ); std::vector v2; v2.push_back( 1 ); v2.push_back( 2 ); std::vector empty; SECTION( "Contains (element)" ) { CHECK_THAT( v, VectorContains( 1 ) ); CHECK_THAT( v, VectorContains( 2 ) ); } SECTION( "Contains (vector)" ) { CHECK_THAT( v, Contains( v2 ) ); v2.push_back( 3 ); // now exactly matches CHECK_THAT( v, Contains( v2 ) ); CHECK_THAT( v, Contains( empty) ); CHECK_THAT( empty, Contains( empty) ); } SECTION( "Equals" ) { // Same vector CHECK_THAT( v, Equals( v ) ); CHECK_THAT( empty, Equals( empty ) ); // Different vector with same elements v2.push_back( 3 ); CHECK_THAT( v, Equals( v2 ) ); } } TEST_CASE( "Vector matchers that fail", "[matchers][vector][.][failing]" ) { std::vector v; v.push_back( 1 ); v.push_back( 2 ); v.push_back( 3 ); std::vector v2; v2.push_back( 1 ); v2.push_back( 2 ); std::vector empty; SECTION( "Contains (element)" ) { CHECK_THAT( v, VectorContains( -1 ) ); CHECK_THAT( empty, VectorContains( 1 ) ); } SECTION( "Contains (vector)" ) { CHECK_THAT( empty, Contains( v) ); v2.push_back( 4 ); CHECK_THAT( v, Contains( v2 ) ); } SECTION( "Equals" ) { CHECK_THAT( v, Equals( v2 ) ); CHECK_THAT( v2, Equals( v ) ); CHECK_THAT( empty, Equals( v ) ); CHECK_THAT( v, Equals( empty ) ); } } catch-1.12.1/projects/SelfTest/MessageTests.cpp000066400000000000000000000074731325474075300214000ustar00rootroot00000000000000/* * Created by Phil on 09/11/2010. * Copyright 2010 Two Blue Cubes Ltd. All rights reserved. * * Distributed under the Boost Software License, Version 1.0. (See accompanying * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) */ #include "catch.hpp" #include #ifdef __clang__ #pragma clang diagnostic ignored "-Wc++98-compat-pedantic" #endif TEST_CASE( "INFO and WARN do not abort tests", "[messages][.]" ) { INFO( "this is a " << "message" ); // This should output the message if a failure occurs WARN( "this is a " << "warning" ); // This should always output the message but then continue } TEST_CASE( "SUCCEED counts as a test pass", "[messages]" ) { SUCCEED( "this is a " << "success" ); } TEST_CASE( "INFO gets logged on failure", "[failing][messages][.]" ) { INFO( "this message should be logged" ); INFO( "so should this" ); int a = 2; REQUIRE( a == 1 ); } TEST_CASE( "INFO gets logged on failure, even if captured before successful assertions", "[failing][messages][.]" ) { INFO( "this message may be logged later" ); int a = 2; CHECK( a == 2 ); INFO( "this message should be logged" ); CHECK( a == 1 ); INFO( "and this, but later" ); CHECK( a == 0 ); INFO( "but not this" ); CHECK( a == 2 ); } TEST_CASE( "FAIL aborts the test", "[failing][messages][.]" ) { FAIL( "This is a " << "failure" ); // This should output the message and abort WARN( "We should never see this"); } TEST_CASE( "FAIL_CHECK does not abort the test", "[failing][messages][.]" ) { FAIL_CHECK( "This is a " << "failure" ); // This should output the message then continue WARN( "This message appears in the output"); } #ifdef CATCH_CONFIG_VARIADIC_MACROS TEST_CASE( "FAIL does not require an argument", "[failing][messages][.]" ) { FAIL(); } TEST_CASE( "SUCCESS does not require an argument", "[messages][.]" ) { SUCCEED(); } #endif TEST_CASE( "Output from all sections is reported", "[failing][messages][.]" ) { SECTION( "one", "" ) { FAIL( "Message from section one" ); } SECTION( "two", "" ) { FAIL( "Message from section two" ); } } TEST_CASE( "Standard output from all sections is reported", "[messages][.]" ) { SECTION( "one", "" ) { std::cout << "Message from section one" << std::endl; } SECTION( "two", "" ) { std::cout << "Message from section two" << std::endl; } } TEST_CASE( "Standard error is reported and redirected", "[messages][.]" ) { SECTION( "std::cerr" ) { std::cerr << "Write to std::cerr" << std::endl; } SECTION( "std::clog" ) { std::clog << "Write to std::clog" << std::endl; } SECTION( "Interleaved writes to cerr and clog" ) { std::cerr << "Inter"; std::clog << "leaved"; std::cerr << ' '; std::clog << "writes"; std::cerr << " to error"; std::clog << " streams\n"; } } TEST_CASE( "SCOPED_INFO is reset for each loop", "[messages][failing][.]" ) { for( int i=0; i<100; i++ ) { SCOPED_INFO( "current counter " << i ); SCOPED_CAPTURE( i ); REQUIRE( i < 10 ); } } TEST_CASE( "The NO_FAIL macro reports a failure but does not fail the test", "[messages]" ) { CHECK_NOFAIL( 1 == 2 ); } TEST_CASE( "just info", "[info][isolated info][messages]" ) { INFO( "this should never be seen" ); } TEST_CASE( "just failure", "[fail][isolated info][.][messages]" ) { FAIL( "Previous info should not be seen" ); } TEST_CASE( "sends information to INFO", "[.][failing]" ) { INFO( "hi" ); int i = 7; CAPTURE( i ); REQUIRE( false ); } TEST_CASE( "Pointers can be converted to strings", "[messages][.]" ) { int p; WARN( "actual address of p: " << &p ); WARN( "toString(p): " << Catch::toString( &p ) ); } catch-1.12.1/projects/SelfTest/MiscTests.cpp000066400000000000000000000241431325474075300207000ustar00rootroot00000000000000/* * Created by Phil on 29/11/2010. * Copyright 2010 Two Blue Cubes Ltd. All rights reserved. * * Distributed under the Boost Software License, Version 1.0. (See accompanying * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) */ #include "catch.hpp" #ifdef __clang__ # pragma clang diagnostic ignored "-Wc++98-compat" # pragma clang diagnostic ignored "-Wc++98-compat-pedantic" #endif #include "../include/internal/catch_xmlwriter.hpp" #include #include TEST_CASE( "random SECTION tests", "[.][sections][failing]" ) { int a = 1; int b = 2; SECTION( "s1", "doesn't equal" ) { REQUIRE( a != b ); REQUIRE( b != a ); } SECTION( "s2", "not equal" ) { REQUIRE( a != b); } } TEST_CASE( "nested SECTION tests", "[.][sections][failing]" ) { int a = 1; int b = 2; SECTION( "s1", "doesn't equal" ) { REQUIRE( a != b ); REQUIRE( b != a ); SECTION( "s2", "not equal" ) { REQUIRE( a != b); } } } TEST_CASE( "more nested SECTION tests", "[sections][failing][.]" ) { int a = 1; int b = 2; SECTION( "s1", "doesn't equal" ) { SECTION( "s2", "equal" ) { REQUIRE( a == b ); } SECTION( "s3", "not equal" ) { REQUIRE( a != b ); } SECTION( "s4", "less than" ) { REQUIRE( a < b ); } } } TEST_CASE( "even more nested SECTION tests", "[sections]" ) { SECTION( "c", "" ) { SECTION( "d (leaf)", "" ) { SUCCEED(""); // avoid failing due to no tests } SECTION( "e (leaf)", "" ) { SUCCEED(""); // avoid failing due to no tests } } SECTION( "f (leaf)", "" ) { SUCCEED(""); // avoid failing due to no tests } } TEST_CASE( "looped SECTION tests", "[.][failing][sections]" ) { int a = 1; for( int b = 0; b < 10; ++b ) { std::ostringstream oss; oss << "b is currently: " << b; SECTION( "s1", oss.str() ) { CHECK( b > a ); } } } TEST_CASE( "looped tests", "[.][failing]" ) { static const int fib[] = { 1, 1, 2, 3, 5, 8, 13, 21 }; for( size_t i=0; i < sizeof(fib)/sizeof(int); ++i ) { INFO( "Testing if fib[" << i << "] (" << fib[i] << ") is even" ); CHECK( ( fib[i] % 2 ) == 0 ); } } TEST_CASE( "Sends stuff to stdout and stderr", "[.]" ) { std::cout << "A string sent directly to stdout" << std::endl; std::cerr << "A string sent directly to stderr" << std::endl; } inline const char* makeString( bool makeNull ) { return makeNull ? CATCH_NULL : "valid string"; } TEST_CASE( "null strings", "" ) { REQUIRE( makeString( false ) != static_cast(CATCH_NULL)); REQUIRE( makeString( true ) == static_cast(CATCH_NULL)); } inline bool testCheckedIf( bool flag ) { CHECKED_IF( flag ) return true; else return false; } TEST_CASE( "checkedIf", "" ) { REQUIRE( testCheckedIf( true ) ); } TEST_CASE( "checkedIf, failing", "[failing][.]" ) { REQUIRE( testCheckedIf( false ) ); } inline bool testCheckedElse( bool flag ) { CHECKED_ELSE( flag ) return false; return true; } TEST_CASE( "checkedElse", "" ) { REQUIRE( testCheckedElse( true ) ); } TEST_CASE( "checkedElse, failing", "[failing][.]" ) { REQUIRE( testCheckedElse( false ) ); } TEST_CASE( "xmlentitycheck", "" ) { SECTION( "embedded xml", "it should be possible to embed xml characters, such as <, \" or &, or even whole documents within an attribute" ) { SUCCEED(""); // We need this here to stop it failing due to no tests } SECTION( "encoded chars", "these should all be encoded: &&&\"\"\"<<<&\"<<&\"" ) { SUCCEED(""); // We need this here to stop it failing due to no tests } } TEST_CASE( "send a single char to INFO", "[failing][.]" ) { INFO(3); REQUIRE(false); } TEST_CASE( "atomic if", "[failing][0]") { size_t x = 0; if( x ) REQUIRE(x > 0); else REQUIRE(x == 0); } inline unsigned int Factorial( unsigned int number ) { // return number <= 1 ? number : Factorial(number-1)*number; return number > 1 ? Factorial(number-1)*number : 1; } TEST_CASE( "Factorials are computed", "[factorial]" ) { REQUIRE( Factorial(0) == 1 ); REQUIRE( Factorial(1) == 1 ); REQUIRE( Factorial(2) == 2 ); REQUIRE( Factorial(3) == 6 ); REQUIRE( Factorial(10) == 3628800 ); } TEST_CASE( "An empty test with no assertions", "[empty]" ) { } TEST_CASE( "Nice descriptive name", "[tag1][tag2][tag3][.]" ) { WARN( "This one ran" ); } TEST_CASE( "first tag", "[tag1]" ) { } TEST_CASE( "second tag", "[tag2]" ) { } // //TEST_CASE( "spawn a new process", "[.]" ) //{ // // !TBD Work in progress // char line[200]; // FILE* output = popen("./CatchSelfTest ./failing/matchers/StartsWith", "r"); // while ( fgets(line, 199, output) ) // std::cout << line; //} TEST_CASE( "vectors can be sized and resized", "[vector]" ) { std::vector v( 5 ); REQUIRE( v.size() == 5 ); REQUIRE( v.capacity() >= 5 ); SECTION( "resizing bigger changes size and capacity", "" ) { v.resize( 10 ); REQUIRE( v.size() == 10 ); REQUIRE( v.capacity() >= 10 ); } SECTION( "resizing smaller changes size but not capacity", "" ) { v.resize( 0 ); REQUIRE( v.size() == 0 ); REQUIRE( v.capacity() >= 5 ); SECTION( "We can use the 'swap trick' to reset the capacity", "" ) { std::vector empty; empty.swap( v ); REQUIRE( v.capacity() == 0 ); } } SECTION( "reserving bigger changes capacity but not size", "" ) { v.reserve( 10 ); REQUIRE( v.size() == 5 ); REQUIRE( v.capacity() >= 10 ); } SECTION( "reserving smaller does not change size or capacity", "" ) { v.reserve( 0 ); REQUIRE( v.size() == 5 ); REQUIRE( v.capacity() >= 5 ); } } // https://github.com/philsquared/Catch/issues/166 TEST_CASE("A couple of nested sections followed by a failure", "[failing][.]") { SECTION("Outer", "") SECTION("Inner", "") SUCCEED("that's not flying - that's failing in style"); FAIL("to infinity and beyond"); } TEST_CASE("not allowed", "[!throws]") { // This test case should not be included if you run with -e on the command line SUCCEED( "" ); } //TEST_CASE( "Is big endian" ) { // CHECK( Catch::Detail::Endianness::which() == Catch::Detail::Endianness::Little ); //} TEST_CASE( "Tabs and newlines show in output", "[.][whitespace][failing]" ) { // Based on issue #242 std::string s1 = "if ($b == 10) {\n\t\t$a\t= 20;\n}"; std::string s2 = "if ($b == 10) {\n\t$a = 20;\n}\n"; CHECK( s1 == s2 ); } TEST_CASE( "toString on const wchar_t const pointer returns the string contents", "[toString]" ) { const wchar_t * const s = L"wide load"; std::string result = Catch::toString( s ); CHECK( result == "\"wide load\"" ); } TEST_CASE( "toString on const wchar_t pointer returns the string contents", "[toString]" ) { const wchar_t * s = L"wide load"; std::string result = Catch::toString( s ); CHECK( result == "\"wide load\"" ); } TEST_CASE( "toString on wchar_t const pointer returns the string contents", "[toString]" ) { wchar_t * const s = const_cast( L"wide load" ); std::string result = Catch::toString( s ); CHECK( result == "\"wide load\"" ); } TEST_CASE( "toString on wchar_t returns the string contents", "[toString]" ) { wchar_t * s = const_cast( L"wide load" ); std::string result = Catch::toString( s ); CHECK( result == "\"wide load\"" ); } inline std::string encode( std::string const& str, Catch::XmlEncode::ForWhat forWhat = Catch::XmlEncode::ForTextNodes ) { std::ostringstream oss; oss << Catch::XmlEncode( str, forWhat ); return oss.str(); } TEST_CASE( "XmlEncode" ) { SECTION( "normal string" ) { REQUIRE( encode( "normal string" ) == "normal string" ); } SECTION( "empty string" ) { REQUIRE( encode( "" ) == "" ); } SECTION( "string with ampersand" ) { REQUIRE( encode( "smith & jones" ) == "smith & jones" ); } SECTION( "string with less-than" ) { REQUIRE( encode( "smith < jones" ) == "smith < jones" ); } SECTION( "string with greater-than" ) { REQUIRE( encode( "smith > jones" ) == "smith > jones" ); REQUIRE( encode( "smith ]]> jones" ) == "smith ]]> jones" ); } SECTION( "string with quotes" ) { std::string stringWithQuotes = "don't \"quote\" me on that"; REQUIRE( encode( stringWithQuotes ) == stringWithQuotes ); REQUIRE( encode( stringWithQuotes, Catch::XmlEncode::ForAttributes ) == "don't "quote" me on that" ); } SECTION( "string with control char (1)" ) { REQUIRE( encode( "[\x01]" ) == "[\\x01]" ); } SECTION( "string with control char (x7F)" ) { REQUIRE( encode( "[\x7F]" ) == "[\\x7F]" ); } } #ifdef CATCH_CONFIG_CPP11_LONG_LONG TEST_CASE( "long long", "[c++11][.]" ) { long long l = std::numeric_limits::max(); REQUIRE( l == std::numeric_limits::max() ); } #endif //TEST_CASE( "Divide by Zero signal handler", "[.][sig]" ) { // int i = 0; // int x = 10/i; // This should cause the signal to fire // CHECK( x == 0 ); //} TEST_CASE( "This test 'should' fail but doesn't", "[.][failing][!shouldfail]" ) { SUCCEED( "oops!" ); } TEST_CASE( "# A test name that starts with a #" ) { SUCCEED( "yay" ); } static int f() { return 1; } TEST_CASE( "#835 -- errno should not be touched by Catch", "[!shouldfail]" ) { errno = 1; CHECK(f() == 0); REQUIRE(errno == 1); // Check that f() doesn't touch errno. } TEST_CASE( "#961 -- Dynamically created sections should all be reported", "[.]" ) { for (char i = '0'; i < '5'; ++i) { SECTION(std::string("Looped section ") + i) { SUCCEED( "Everything is OK" ); } } } catch-1.12.1/projects/SelfTest/PartTrackerTests.cpp000066400000000000000000000255111325474075300222270ustar00rootroot00000000000000/* * Created by Phil on 1/10/2015. * Copyright 2015 Two Blue Cubes Ltd * * Distributed under the Boost Software License, Version 1.0. (See accompanying * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) */ #include "internal/catch_suppress_warnings.h" #include "internal/catch_test_case_tracker.hpp" namespace Catch { class LocalContext { public: TrackerContext& operator()() const { return TrackerContext::instance(); } }; } // namespace Catch inline Catch::TrackerContext& C_A_T_C_H_Context() { return Catch::TrackerContext::instance(); } // ------------------- #include "catch.hpp" using namespace Catch; //inline void testCase( Catch::LocalContext const& C_A_T_C_H_Context ) { // // REQUIRE( C_A_T_C_H_Context().i() == 42 ); //} Catch::TestCaseTracking::NameAndLocation makeNAL( std::string const& name ) { return Catch::TestCaseTracking::NameAndLocation( name, Catch::SourceLineInfo() ); } TEST_CASE( "Tracker", "" ) { TrackerContext ctx; ctx.startRun(); ctx.startCycle(); ITracker& testCase = SectionTracker::acquire( ctx, makeNAL( "Testcase" ) ); REQUIRE( testCase.isOpen() ); ITracker& s1 = SectionTracker::acquire( ctx, makeNAL( "S1" ) ); REQUIRE( s1.isOpen() ); SECTION( "successfully close one section", "" ) { s1.close(); REQUIRE( s1.isSuccessfullyCompleted() ); REQUIRE( testCase.isComplete() == false ); testCase.close(); REQUIRE( ctx.completedCycle() ); REQUIRE( testCase.isSuccessfullyCompleted() ); } SECTION( "fail one section", "" ) { s1.fail(); REQUIRE( s1.isComplete() ); REQUIRE( s1.isSuccessfullyCompleted() == false ); REQUIRE( testCase.isComplete() == false ); testCase.close(); REQUIRE( ctx.completedCycle() ); REQUIRE( testCase.isSuccessfullyCompleted() == false ); SECTION( "re-enter after failed section", "" ) { ctx.startCycle(); ITracker& testCase2 = SectionTracker::acquire( ctx, makeNAL( "Testcase" ) ); REQUIRE( testCase2.isOpen() ); ITracker& s1b = SectionTracker::acquire( ctx, makeNAL( "S1" ) ); REQUIRE( s1b.isOpen() == false ); testCase2.close(); REQUIRE( ctx.completedCycle() ); REQUIRE( testCase.isComplete() ); REQUIRE( testCase.isSuccessfullyCompleted() ); } SECTION( "re-enter after failed section and find next section", "" ) { ctx.startCycle(); ITracker& testCase2 = SectionTracker::acquire( ctx, makeNAL( "Testcase" ) ); REQUIRE( testCase2.isOpen() ); ITracker& s1b = SectionTracker::acquire( ctx, makeNAL( "S1" ) ); REQUIRE( s1b.isOpen() == false ); ITracker& s2 = SectionTracker::acquire( ctx, makeNAL( "S2" ) ); REQUIRE( s2.isOpen() ); s2.close(); REQUIRE( ctx.completedCycle() ); testCase2.close(); REQUIRE( testCase.isComplete() ); REQUIRE( testCase.isSuccessfullyCompleted() ); } } SECTION( "successfully close one section, then find another", "" ) { s1.close(); ITracker& s2 = SectionTracker::acquire( ctx, makeNAL( "S2" ) ); REQUIRE( s2.isOpen() == false ); testCase.close(); REQUIRE( testCase.isComplete() == false ); SECTION( "Re-enter - skips S1 and enters S2", "" ) { ctx.startCycle(); ITracker& testCase2 = SectionTracker::acquire( ctx, makeNAL( "Testcase" ) ); REQUIRE( testCase2.isOpen() ); ITracker& s1b = SectionTracker::acquire( ctx, makeNAL( "S1" ) ); REQUIRE( s1b.isOpen() == false ); ITracker& s2b = SectionTracker::acquire( ctx, makeNAL( "S2" ) ); REQUIRE( s2b.isOpen() ); REQUIRE( ctx.completedCycle() == false ); SECTION ("Successfully close S2") { s2b.close(); REQUIRE( ctx.completedCycle() ); REQUIRE( s2b.isSuccessfullyCompleted() ); REQUIRE( testCase2.isComplete() == false ); testCase2.close(); REQUIRE( testCase2.isSuccessfullyCompleted() ); } SECTION ("fail S2") { s2b.fail(); REQUIRE( ctx.completedCycle() ); REQUIRE( s2b.isComplete() ); REQUIRE( s2b.isSuccessfullyCompleted() == false ); testCase2.close(); REQUIRE( testCase2.isSuccessfullyCompleted() == false ); // Need a final cycle ctx.startCycle(); ITracker& testCase3 = SectionTracker::acquire( ctx, makeNAL( "Testcase" ) ); REQUIRE( testCase3.isOpen() ); ITracker& s1c = SectionTracker::acquire( ctx, makeNAL( "S1" ) ); REQUIRE( s1c.isOpen() == false ); ITracker& s2c = SectionTracker::acquire( ctx, makeNAL( "S2" ) ); REQUIRE( s2c.isOpen() == false ); testCase3.close(); REQUIRE( testCase3.isSuccessfullyCompleted() ); } } } SECTION( "open a nested section", "" ) { ITracker& s2 = SectionTracker::acquire( ctx, makeNAL( "S2" ) ); REQUIRE( s2.isOpen() ); s2.close(); REQUIRE( s2.isComplete() ); REQUIRE( s1.isComplete() == false ); s1.close(); REQUIRE( s1.isComplete() ); REQUIRE( testCase.isComplete() == false ); testCase.close(); REQUIRE( testCase.isComplete() ); } SECTION( "start a generator", "" ) { IndexTracker& g1 = IndexTracker::acquire( ctx, makeNAL( "G1" ), 2 ); REQUIRE( g1.isOpen() ); REQUIRE( g1.index() == 0 ); REQUIRE( g1.isComplete() == false ); REQUIRE( s1.isComplete() == false ); SECTION( "close outer section" ) { s1.close(); REQUIRE( s1.isComplete() == false ); testCase.close(); REQUIRE( testCase.isSuccessfullyCompleted() == false ); SECTION( "Re-enter for second generation", "" ) { ctx.startCycle(); ITracker& testCase2 = SectionTracker::acquire( ctx, makeNAL( "Testcase" ) ); REQUIRE( testCase2.isOpen() ); ITracker& s1b = SectionTracker::acquire( ctx, makeNAL( "S1" ) ); REQUIRE( s1b.isOpen() ); IndexTracker& g1b = IndexTracker::acquire( ctx, makeNAL( "G1" ), 2 ); REQUIRE( g1b.isOpen() ); REQUIRE( g1b.index() == 1 ); REQUIRE( s1.isComplete() == false ); s1b.close(); REQUIRE( s1b.isComplete() ); REQUIRE( g1b.isComplete() ); testCase2.close(); REQUIRE( testCase2.isComplete() ); } } SECTION( "Start a new inner section", "" ) { ITracker& s2 = SectionTracker::acquire( ctx, makeNAL( "S2" ) ); REQUIRE( s2.isOpen() ); s2.close(); REQUIRE( s2.isComplete() ); s1.close(); REQUIRE( s1.isComplete() == false ); testCase.close(); REQUIRE( testCase.isComplete() == false ); SECTION( "Re-enter for second generation", "" ) { ctx.startCycle(); ITracker& testCase2 = SectionTracker::acquire( ctx, makeNAL( "Testcase" ) ); REQUIRE( testCase2.isOpen() ); ITracker& s1b = SectionTracker::acquire( ctx, makeNAL( "S1" ) ); REQUIRE( s1b.isOpen() ); // generator - next value IndexTracker& g1b = IndexTracker::acquire( ctx, makeNAL( "G1" ), 2 ); REQUIRE( g1b.isOpen() ); REQUIRE( g1b.index() == 1 ); // inner section again ITracker& s2b = SectionTracker::acquire( ctx, makeNAL( "S2" ) ); REQUIRE( s2b.isOpen() ); s2b.close(); REQUIRE( s2b.isComplete() ); s1b.close(); REQUIRE( g1b.isComplete() ); REQUIRE( s1b.isComplete() ); testCase2.close(); REQUIRE( testCase2.isComplete() ); } } SECTION( "Fail an inner section", "" ) { ITracker& s2 = SectionTracker::acquire( ctx, makeNAL( "S2" ) ); REQUIRE( s2.isOpen() ); s2.fail(); REQUIRE( s2.isComplete() ); REQUIRE( s2.isSuccessfullyCompleted() == false ); s1.close(); REQUIRE( s1.isComplete() == false ); testCase.close(); REQUIRE( testCase.isComplete() == false ); SECTION( "Re-enter for second generation", "" ) { ctx.startCycle(); ITracker& testCase2 = SectionTracker::acquire( ctx, makeNAL( "Testcase" ) ); REQUIRE( testCase2.isOpen() ); ITracker& s1b = SectionTracker::acquire( ctx, makeNAL( "S1" ) ); REQUIRE( s1b.isOpen() ); // generator - still same value IndexTracker& g1b = IndexTracker::acquire( ctx, makeNAL( "G1" ), 2 ); REQUIRE( g1b.isOpen() ); REQUIRE( g1b.index() == 0 ); // inner section again - this time won't open ITracker& s2b = SectionTracker::acquire( ctx, makeNAL( "S2" ) ); REQUIRE( s2b.isOpen() == false ); s1b.close(); REQUIRE( g1b.isComplete() == false ); REQUIRE( s1b.isComplete() == false ); testCase2.close(); REQUIRE( testCase2.isComplete() == false ); // Another cycle - now should complete ctx.startCycle(); ITracker& testCase3 = SectionTracker::acquire( ctx, makeNAL( "Testcase" ) ); REQUIRE( testCase3.isOpen() ); ITracker& s1c = SectionTracker::acquire( ctx, makeNAL( "S1" ) ); REQUIRE( s1c.isOpen() ); // generator - now next value IndexTracker& g1c = IndexTracker::acquire( ctx, makeNAL( "G1" ), 2 ); REQUIRE( g1c.isOpen() ); REQUIRE( g1c.index() == 1 ); // inner section - now should open again ITracker& s2c = SectionTracker::acquire( ctx, makeNAL( "S2" ) ); REQUIRE( s2c.isOpen() ); s2c.close(); REQUIRE( s2c.isComplete() ); s1c.close(); REQUIRE( g1c.isComplete() ); REQUIRE( s1c.isComplete() ); testCase3.close(); REQUIRE( testCase3.isComplete() ); } } // !TBD" // nested generator // two sections within a generator } } catch-1.12.1/projects/SelfTest/SurrogateCpps/000077500000000000000000000000001325474075300210535ustar00rootroot00000000000000catch-1.12.1/projects/SelfTest/SurrogateCpps/catch_common.cpp000066400000000000000000000002611325474075300242100ustar00rootroot00000000000000// This file is only here to verify (to the extent possible) the self sufficiency of the header #include "internal/catch_suppress_warnings.h" #include "internal/catch_common.h" catch-1.12.1/projects/SelfTest/SurrogateCpps/catch_console_colour.cpp000066400000000000000000000002731325474075300257500ustar00rootroot00000000000000// This file is only here to verify (to the extent possible) the self sufficiency of the header #include "internal/catch_suppress_warnings.h" #include "internal/catch_console_colour.hpp" catch-1.12.1/projects/SelfTest/SurrogateCpps/catch_debugger.cpp000066400000000000000000000002051325474075300245020ustar00rootroot00000000000000// This file is only here to verify (to the extent possible) the self sufficiency of the header #include "internal/catch_debugger.h" catch-1.12.1/projects/SelfTest/SurrogateCpps/catch_interfaces_capture.cpp000066400000000000000000000002751325474075300265730ustar00rootroot00000000000000// This file is only here to verify (to the extent possible) the self sufficiency of the header #include "internal/catch_suppress_warnings.h" #include "internal/catch_interfaces_capture.h" catch-1.12.1/projects/SelfTest/SurrogateCpps/catch_interfaces_config.cpp000066400000000000000000000001341325474075300263670ustar00rootroot00000000000000#include "internal/catch_suppress_warnings.h" #include "internal/catch_interfaces_config.h" catch-1.12.1/projects/SelfTest/SurrogateCpps/catch_interfaces_exception.cpp000066400000000000000000000001371325474075300271230ustar00rootroot00000000000000#include "internal/catch_suppress_warnings.h" #include "internal/catch_interfaces_exception.h" catch-1.12.1/projects/SelfTest/SurrogateCpps/catch_interfaces_generators.cpp000066400000000000000000000000621325474075300272730ustar00rootroot00000000000000#include "internal/catch_interfaces_generators.h" catch-1.12.1/projects/SelfTest/SurrogateCpps/catch_interfaces_registry_hub.cpp000066400000000000000000000003021325474075300276250ustar00rootroot00000000000000// This file is only here to verify (to the extent possible) the self sufficiency of the header #include "internal/catch_suppress_warnings.h" #include "internal/catch_interfaces_registry_hub.h" catch-1.12.1/projects/SelfTest/SurrogateCpps/catch_interfaces_reporter.cpp000066400000000000000000000001361325474075300267660ustar00rootroot00000000000000#include "internal/catch_suppress_warnings.h" #include "internal/catch_interfaces_reporter.h" catch-1.12.1/projects/SelfTest/SurrogateCpps/catch_interfaces_runner.cpp000066400000000000000000000000561325474075300264360ustar00rootroot00000000000000#include "internal/catch_interfaces_runner.h" catch-1.12.1/projects/SelfTest/SurrogateCpps/catch_interfaces_testcase.cpp000066400000000000000000000001361325474075300267370ustar00rootroot00000000000000#include "internal/catch_suppress_warnings.h" #include "internal/catch_interfaces_testcase.h" catch-1.12.1/projects/SelfTest/SurrogateCpps/catch_message.cpp000066400000000000000000000002621325474075300243450ustar00rootroot00000000000000// This file is only here to verify (to the extent possible) the self sufficiency of the header #include "internal/catch_suppress_warnings.h" #include "internal/catch_message.h" catch-1.12.1/projects/SelfTest/SurrogateCpps/catch_option.cpp000066400000000000000000000002631325474075300242320ustar00rootroot00000000000000// This file is only here to verify (to the extent possible) the self sufficiency of the header #include "internal/catch_suppress_warnings.h" #include "internal/catch_option.hpp" catch-1.12.1/projects/SelfTest/SurrogateCpps/catch_ptr.cpp000066400000000000000000000002601325474075300235240ustar00rootroot00000000000000// This file is only here to verify (to the extent possible) the self sufficiency of the header #include "internal/catch_suppress_warnings.h" #include "internal/catch_ptr.hpp" catch-1.12.1/projects/SelfTest/SurrogateCpps/catch_stream.cpp000066400000000000000000000002611325474075300242130ustar00rootroot00000000000000// This file is only here to verify (to the extent possible) the self sufficiency of the header #include "internal/catch_suppress_warnings.h" #include "internal/catch_stream.h" catch-1.12.1/projects/SelfTest/SurrogateCpps/catch_streambuf.cpp000066400000000000000000000002641325474075300247130ustar00rootroot00000000000000// This file is only here to verify (to the extent possible) the self sufficiency of the header #include "internal/catch_suppress_warnings.h" #include "internal/catch_streambuf.h" catch-1.12.1/projects/SelfTest/SurrogateCpps/catch_test_case_tracker.cpp000066400000000000000000000002201325474075300264000ustar00rootroot00000000000000// This file is only here to verify (to the extent possible) the self sufficiency of the header #include "internal/catch_test_case_tracker.hpp" catch-1.12.1/projects/SelfTest/SurrogateCpps/catch_test_spec.cpp000066400000000000000000000002661325474075300247160ustar00rootroot00000000000000// This file is only here to verify (to the extent possible) the self sufficiency of the header #include "internal/catch_suppress_warnings.h" #include "internal/catch_test_spec.hpp" catch-1.12.1/projects/SelfTest/SurrogateCpps/catch_xmlwriter.cpp000066400000000000000000000003441325474075300247570ustar00rootroot00000000000000// This file is only here to verify (to the extent possible) the self sufficiency of the header #include "internal/catch_suppress_warnings.h" #include "internal/catch_xmlwriter.hpp" #include "internal/catch_reenable_warnings.h" catch-1.12.1/projects/SelfTest/TagAliasTests.cpp000066400000000000000000000030641325474075300214710ustar00rootroot00000000000000/* * Created by Phil on 27/06/2014. * Copyright 2014 Two Blue Cubes Ltd. All rights reserved. * * Distributed under the Boost Software License, Version 1.0. (See accompanying * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) */ #include "catch.hpp" #include "internal/catch_tag_alias_registry.h" TEST_CASE( "Tag alias can be registered against tag patterns", "" ) { using namespace Catch::Matchers; Catch::TagAliasRegistry registry; registry.add( "[@zzz]", "[one][two]", Catch::SourceLineInfo( "file", 2 ) ); SECTION( "The same tag alias can only be registered once", "" ) { try { registry.add( "[@zzz]", "[one][two]", Catch::SourceLineInfo( "file", 10 ) ); FAIL( "expected exception" ); } catch( std::exception& ex ) { std::string what = ex.what(); CHECK_THAT( what, Contains( "[@zzz]" ) ); CHECK_THAT( what, Contains( "file" ) ); CHECK_THAT( what, Contains( "2" ) ); CHECK_THAT( what, Contains( "10" ) ); } } SECTION( "Tag aliases must be of the form [@name]", "" ) { CHECK_THROWS( registry.add( "[no ampersat]", "", Catch::SourceLineInfo( "file", 3 ) ) ); CHECK_THROWS( registry.add( "[the @ is not at the start]", "", Catch::SourceLineInfo( "file", 3 ) ) ); CHECK_THROWS( registry.add( "@no square bracket at start]", "", Catch::SourceLineInfo( "file", 3 ) ) ); CHECK_THROWS( registry.add( "[@no square bracket at end", "", Catch::SourceLineInfo( "file", 3 ) ) ); } } catch-1.12.1/projects/SelfTest/TestMain.cpp000066400000000000000000000446451325474075300205170ustar00rootroot00000000000000/* * Created by Phil on 22/10/2010. * Copyright 2010 Two Blue Cubes Ltd * * Distributed under the Boost Software License, Version 1.0. (See accompanying * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) */ #define CATCH_CONFIG_MAIN #include "catch.hpp" #include "../include/reporters/catch_reporter_teamcity.hpp" #include "../include/reporters/catch_reporter_tap.hpp" #include "../include/reporters/catch_reporter_automake.hpp" // Some example tag aliases CATCH_REGISTER_TAG_ALIAS( "[@nhf]", "[failing]~[.]" ) CATCH_REGISTER_TAG_ALIAS( "[@tricky]", "[tricky]~[.]" ) #ifdef __clang__ # pragma clang diagnostic ignored "-Wpadded" # pragma clang diagnostic ignored "-Wweak-vtables" # pragma clang diagnostic ignored "-Wc++98-compat" #endif template void parseIntoConfig( const char * (&argv)[size], Catch::ConfigData& config ) { Catch::Clara::CommandLine parser = Catch::makeCommandLineParser(); parser.parseInto( Catch::Clara::argsToVector( size, argv ), config ); } template std::string parseIntoConfigAndReturnError( const char * (&argv)[size], Catch::ConfigData& config ) { try { parseIntoConfig( argv, config ); FAIL( "expected exception" ); } catch( std::exception& ex ) { return ex.what(); } return ""; } inline Catch::TestCase fakeTestCase( const char* name, const char* desc = "" ){ return Catch::makeTestCase( CATCH_NULL, "", name, desc, CATCH_INTERNAL_LINEINFO ); } TEST_CASE( "Process can be configured on command line", "[config][command-line]" ) { using namespace Catch::Matchers; Catch::ConfigData config; SECTION( "empty args don't cause a crash" ) { Catch::Clara::CommandLine parser = Catch::makeCommandLineParser(); CHECK_NOTHROW( parser.parseInto( std::vector(), config ) ); CHECK( config.processName == "" ); } SECTION( "default - no arguments", "" ) { const char* argv[] = { "test" }; CHECK_NOTHROW( parseIntoConfig( argv, config ) ); CHECK( config.processName == "test" ); CHECK( config.shouldDebugBreak == false ); CHECK( config.abortAfter == -1 ); CHECK( config.noThrow == false ); CHECK( config.reporterNames.empty() ); } SECTION( "test lists", "" ) { SECTION( "1 test", "Specify one test case using" ) { const char* argv[] = { "test", "test1" }; CHECK_NOTHROW( parseIntoConfig( argv, config ) ); Catch::Config cfg( config ); REQUIRE( cfg.testSpec().matches( fakeTestCase( "notIncluded" ) ) == false ); REQUIRE( cfg.testSpec().matches( fakeTestCase( "test1" ) ) ); } SECTION( "Specify one test case exclusion using exclude:", "" ) { const char* argv[] = { "test", "exclude:test1" }; CHECK_NOTHROW( parseIntoConfig( argv, config ) ); Catch::Config cfg( config ); REQUIRE( cfg.testSpec().matches( fakeTestCase( "test1" ) ) == false ); REQUIRE( cfg.testSpec().matches( fakeTestCase( "alwaysIncluded" ) ) ); } SECTION( "Specify one test case exclusion using ~", "" ) { const char* argv[] = { "test", "~test1" }; CHECK_NOTHROW( parseIntoConfig( argv, config ) ); Catch::Config cfg( config ); REQUIRE( cfg.testSpec().matches( fakeTestCase( "test1" ) ) == false ); REQUIRE( cfg.testSpec().matches( fakeTestCase( "alwaysIncluded" ) ) ); } } SECTION( "reporter", "" ) { SECTION( "-r/console", "" ) { const char* argv[] = { "test", "-r", "console" }; CHECK_NOTHROW( parseIntoConfig( argv, config ) ); REQUIRE( config.reporterNames[0] == "console" ); } SECTION( "-r/xml", "" ) { const char* argv[] = { "test", "-r", "xml" }; CHECK_NOTHROW( parseIntoConfig( argv, config ) ); REQUIRE( config.reporterNames[0] == "xml" ); } SECTION( "-r xml and junit", "" ) { const char* argv[] = { "test", "-r", "xml", "-r", "junit" }; CHECK_NOTHROW( parseIntoConfig( argv, config ) ); REQUIRE( config.reporterNames.size() == 2 ); REQUIRE( config.reporterNames[0] == "xml" ); REQUIRE( config.reporterNames[1] == "junit" ); } SECTION( "--reporter/junit", "" ) { const char* argv[] = { "test", "--reporter", "junit" }; CHECK_NOTHROW( parseIntoConfig( argv, config ) ); REQUIRE( config.reporterNames[0] == "junit" ); } } SECTION( "debugger", "" ) { SECTION( "-b", "" ) { const char* argv[] = { "test", "-b" }; CHECK_NOTHROW( parseIntoConfig( argv, config ) ); REQUIRE( config.shouldDebugBreak == true ); } SECTION( "--break", "" ) { const char* argv[] = { "test", "--break" }; CHECK_NOTHROW( parseIntoConfig( argv, config ) ); REQUIRE( config.shouldDebugBreak ); } } SECTION( "abort", "" ) { SECTION( "-a aborts after first failure", "" ) { const char* argv[] = { "test", "-a" }; CHECK_NOTHROW( parseIntoConfig( argv, config ) ); REQUIRE( config.abortAfter == 1 ); } SECTION( "-x 2 aborts after two failures", "" ) { const char* argv[] = { "test", "-x", "2" }; CHECK_NOTHROW( parseIntoConfig( argv, config ) ); REQUIRE( config.abortAfter == 2 ); } SECTION( "-x must be greater than zero", "" ) { const char* argv[] = { "test", "-x", "0" }; REQUIRE_THAT( parseIntoConfigAndReturnError( argv, config ), Contains( "greater than zero" ) ); } SECTION( "-x must be numeric", "" ) { const char* argv[] = { "test", "-x", "oops" }; REQUIRE_THAT( parseIntoConfigAndReturnError( argv, config ), Contains( "-x" ) ); } } SECTION( "nothrow", "" ) { SECTION( "-e", "" ) { const char* argv[] = { "test", "-e" }; CHECK_NOTHROW( parseIntoConfig( argv, config ) ); REQUIRE( config.noThrow == true ); } SECTION( "--nothrow", "" ) { const char* argv[] = { "test", "--nothrow" }; CHECK_NOTHROW( parseIntoConfig( argv, config ) ); REQUIRE( config.noThrow == true ); } } SECTION( "output filename", "" ) { SECTION( "-o filename", "" ) { const char* argv[] = { "test", "-o", "filename.ext" }; CHECK_NOTHROW( parseIntoConfig( argv, config ) ); REQUIRE( config.outputFilename == "filename.ext" ); } SECTION( "--out", "" ) { const char* argv[] = { "test", "--out", "filename.ext" }; CHECK_NOTHROW( parseIntoConfig( argv, config ) ); REQUIRE( config.outputFilename == "filename.ext" ); } } SECTION( "combinations", "" ) { SECTION( "Single character flags can be combined", "" ) { const char* argv[] = { "test", "-abe" }; CHECK_NOTHROW( parseIntoConfig( argv, config ) ); CHECK( config.abortAfter == 1 ); CHECK( config.shouldDebugBreak ); CHECK( config.noThrow == true ); } } SECTION( "use-colour", "") { using Catch::UseColour; SECTION( "without option", "" ) { const char* argv[] = { "test" }; CHECK_NOTHROW( parseIntoConfig( argv, config ) ); REQUIRE( config.useColour == UseColour::Auto ); } SECTION( "auto", "" ) { const char* argv[] = { "test", "--use-colour", "auto" }; CHECK_NOTHROW( parseIntoConfig( argv, config ) ); REQUIRE( config.useColour == UseColour::Auto ); } SECTION( "yes", "" ) { const char* argv[] = { "test", "--use-colour", "yes" }; CHECK_NOTHROW( parseIntoConfig( argv, config ) ); REQUIRE( config.useColour == UseColour::Yes ); } SECTION( "no", "" ) { const char* argv[] = { "test", "--use-colour", "no" }; CHECK_NOTHROW( parseIntoConfig( argv, config ) ); REQUIRE( config.useColour == UseColour::No ); } SECTION( "error", "" ) { const char* argv[] = { "test", "--use-colour", "wrong" }; REQUIRE_THROWS_WITH( parseIntoConfig( argv, config ), Contains( "colour mode must be one of" ) ); } } } TEST_CASE( "Long strings can be wrapped", "[wrap]" ) { using namespace Catch; SECTION( "plain string", "" ) { // guide: 123456789012345678 std::string testString = "one two three four"; SECTION( "No wrapping", "" ) { CHECK( Text( testString, TextAttributes().setWidth( 80 ) ).toString() == testString ); CHECK( Text( testString, TextAttributes().setWidth( 18 ) ).toString() == testString ); } SECTION( "Wrapped once", "" ) { CHECK( Text( testString, TextAttributes().setWidth( 17 ) ).toString() == "one two three\nfour" ); CHECK( Text( testString, TextAttributes().setWidth( 16 ) ).toString() == "one two three\nfour" ); CHECK( Text( testString, TextAttributes().setWidth( 14 ) ).toString() == "one two three\nfour" ); CHECK( Text( testString, TextAttributes().setWidth( 13 ) ).toString() == "one two three\nfour" ); CHECK( Text( testString, TextAttributes().setWidth( 12 ) ).toString() == "one two\nthree four" ); } SECTION( "Wrapped twice", "" ) { CHECK( Text( testString, TextAttributes().setWidth( 9 ) ).toString() == "one two\nthree\nfour" ); CHECK( Text( testString, TextAttributes().setWidth( 8 ) ).toString() == "one two\nthree\nfour" ); CHECK( Text( testString, TextAttributes().setWidth( 7 ) ).toString() == "one two\nthree\nfour" ); } SECTION( "Wrapped three times", "" ) { CHECK( Text( testString, TextAttributes().setWidth( 6 ) ).toString() == "one\ntwo\nthree\nfour" ); CHECK( Text( testString, TextAttributes().setWidth( 5 ) ).toString() == "one\ntwo\nthree\nfour" ); } SECTION( "Short wrap", "" ) { CHECK( Text( "abcdef", TextAttributes().setWidth( 4 ) ).toString() == "abc-\ndef" ); CHECK( Text( "abcdefg", TextAttributes().setWidth( 4 ) ).toString() == "abc-\ndefg" ); CHECK( Text( "abcdefgh", TextAttributes().setWidth( 4 ) ).toString() == "abc-\ndef-\ngh" ); CHECK( Text( testString, TextAttributes().setWidth( 4 ) ).toString() == "one\ntwo\nthr-\nee\nfour" ); CHECK( Text( testString, TextAttributes().setWidth( 3 ) ).toString() == "one\ntwo\nth-\nree\nfo-\nur" ); } SECTION( "As container", "" ) { Text text( testString, TextAttributes().setWidth( 6 ) ); REQUIRE( text.size() == 4 ); CHECK( text[0] == "one" ); CHECK( text[1] == "two" ); CHECK( text[2] == "three" ); CHECK( text[3] == "four" ); } SECTION( "Indent first line differently", "" ) { Text text( testString, TextAttributes() .setWidth( 10 ) .setIndent( 4 ) .setInitialIndent( 1 ) ); CHECK( text.toString() == " one two\n three\n four" ); } } SECTION( "With newlines", "" ) { // guide: 1234567890123456789 std::string testString = "one two\nthree four"; SECTION( "No wrapping" , "" ) { CHECK( Text( testString, TextAttributes().setWidth( 80 ) ).toString() == testString ); CHECK( Text( testString, TextAttributes().setWidth( 18 ) ).toString() == testString ); CHECK( Text( testString, TextAttributes().setWidth( 10 ) ).toString() == testString ); } SECTION( "Trailing newline" , "" ) { CHECK( Text( "abcdef\n", TextAttributes().setWidth( 10 ) ).toString() == "abcdef" ); CHECK( Text( "abcdef", TextAttributes().setWidth( 6 ) ).toString() == "abcdef" ); CHECK( Text( "abcdef\n", TextAttributes().setWidth( 6 ) ).toString() == "abcdef" ); CHECK( Text( "abcdef\n", TextAttributes().setWidth( 5 ) ).toString() == "abcd-\nef" ); } SECTION( "Wrapped once", "" ) { CHECK( Text( testString, TextAttributes().setWidth( 9 ) ).toString() == "one two\nthree\nfour" ); CHECK( Text( testString, TextAttributes().setWidth( 8 ) ).toString() == "one two\nthree\nfour" ); CHECK( Text( testString, TextAttributes().setWidth( 7 ) ).toString() == "one two\nthree\nfour" ); } SECTION( "Wrapped twice", "" ) { CHECK( Text( testString, TextAttributes().setWidth( 6 ) ).toString() == "one\ntwo\nthree\nfour" ); } } SECTION( "With wrap-before/ after characters", "" ) { std::string testString = "one,two(three) "; SECTION( "No wrapping", "" ) { CHECK( Text( testString, TextAttributes().setWidth( 80 ) ).toString() == testString ); CHECK( Text( testString, TextAttributes().setWidth( 24 ) ).toString() == testString ); } SECTION( "Wrap before", "" ) { CHECK( Text( testString, TextAttributes().setWidth( 11 ) ).toString() == "one,two\n(three)\n" ); } SECTION( "Wrap after", "" ) { CHECK( Text( testString, TextAttributes().setWidth( 6 ) ).toString() == "one,\ntwo\n(thre-\ne)\n" ); CHECK( Text( testString, TextAttributes().setWidth( 5 ) ).toString() == "one,\ntwo\n(thr-\nee)\n" ); CHECK( Text( testString, TextAttributes().setWidth( 4 ) ).toString() == "one,\ntwo\n(th-\nree)\n" ); } } } using namespace Catch; class ColourString { public: struct ColourIndex { ColourIndex( Colour::Code _colour, std::size_t _fromIndex, std::size_t _toIndex ) : colour( _colour ), fromIndex( _fromIndex ), toIndex( _toIndex ) {} Colour::Code colour; std::size_t fromIndex; std::size_t toIndex; }; ColourString( std::string const& _string ) : string( _string ) {} ColourString( std::string const& _string, std::vector const& _colours ) : string( _string ), colours( _colours ) {} ColourString& addColour( Colour::Code colour, int _index ) { colours.push_back( ColourIndex( colour, resolveRelativeIndex( _index ), resolveRelativeIndex( _index )+1 ) ); return *this; } ColourString& addColour( Colour::Code colour, int _fromIndex, int _toIndex ) { colours.push_back( ColourIndex( colour, resolveRelativeIndex(_fromIndex), resolveLastRelativeIndex( _toIndex ) ) ); return *this; } void writeToStream( std::ostream& _stream ) const { std::size_t last = 0; for( std::size_t i = 0; i < colours.size(); ++i ) { ColourIndex const& index = colours[i]; if( index.fromIndex > last ) _stream << string.substr( last, index.fromIndex-last ); { Colour colourGuard( index.colour ); _stream << string.substr( index.fromIndex, index.toIndex-index.fromIndex ); } last = index.toIndex; } if( last < string.size() ) _stream << string.substr( last ); } friend std::ostream& operator << ( std::ostream& _stream, ColourString const& _colourString ) { _colourString.writeToStream( _stream ); return _stream; } private: std::size_t resolveLastRelativeIndex( int _index ) { std::size_t index = resolveRelativeIndex( _index ); return index == 0 ? string.size() : index; } std::size_t resolveRelativeIndex( int _index ) { return static_cast( _index >= 0 ? _index : static_cast( string.size() )+_index ); } std::string string; std::vector colours; }; TEST_CASE( "replaceInPlace", "" ) { std::string letters = "abcdefcg"; SECTION( "replace single char" ) { CHECK( replaceInPlace( letters, "b", "z" ) ); CHECK( letters == "azcdefcg" ); } SECTION( "replace two chars" ) { CHECK( replaceInPlace( letters, "c", "z" ) ); CHECK( letters == "abzdefzg" ); } SECTION( "replace first char" ) { CHECK( replaceInPlace( letters, "a", "z" ) ); CHECK( letters == "zbcdefcg" ); } SECTION( "replace last char" ) { CHECK( replaceInPlace( letters, "g", "z" ) ); CHECK( letters == "abcdefcz" ); } SECTION( "replace all chars" ) { CHECK( replaceInPlace( letters, letters, "replaced" ) ); CHECK( letters == "replaced" ); } SECTION( "replace no chars" ) { CHECK_FALSE( replaceInPlace( letters, "x", "z" ) ); CHECK( letters == letters ); } SECTION( "escape '" ) { std::string s = "didn't"; CHECK( replaceInPlace( s, "'", "|'" ) ); CHECK( s == "didn|'t" ); } } // !TBD: This will be folded into Text class TEST_CASE( "Strings can be rendered with colour", "[.colour]" ) { { ColourString cs( "hello" ); cs .addColour( Colour::Red, 0 ) .addColour( Colour::Green, -1 ); Catch::cout() << cs << std::endl; } { ColourString cs( "hello" ); cs .addColour( Colour::Blue, 1, -2 ); Catch::cout() << cs << std::endl; } } TEST_CASE( "Text can be formatted using the Text class", "" ) { CHECK( Text( "hi there" ).toString() == "hi there" ); TextAttributes narrow; narrow.setWidth( 6 ); CHECK( Text( "hi there", narrow ).toString() == "hi\nthere" ); } TEST_CASE( "Long text is truncated", "[Text][Truncated]" ) { std::string longLine( 90, '*' ); std::ostringstream oss; for(int i = 0; i < 600; ++i ) oss << longLine << longLine << "\n"; Text t( oss.str() ); CHECK_THAT( t.toString(), EndsWith( "... message truncated due to excessive size" ) ); } inline void manuallyRegisteredTestFunction() { SUCCEED( "was called" ); } struct AutoTestReg { AutoTestReg() { REGISTER_TEST_CASE( manuallyRegisteredTestFunction, "ManuallyRegistered", "" ); } }; AutoTestReg autoTestReg; catch-1.12.1/projects/SelfTest/ToStringGeneralTests.cpp000066400000000000000000000024761325474075300230610ustar00rootroot00000000000000/* * Created by Martin on 17/02/2017. * * Distributed under the Boost Software License, Version 1.0. (See accompanying * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) */ #include "catch.hpp" TEST_CASE( "Character pretty printing" ){ SECTION("Specifically escaped"){ char tab = '\t'; char newline = '\n'; char carr_return = '\r'; char form_feed = '\f'; CHECK(tab == '\t'); CHECK(newline == '\n'); CHECK(carr_return == '\r'); CHECK(form_feed == '\f'); } SECTION("General chars"){ char space = ' '; CHECK(space == ' '); char chars[] = {'a', 'z', 'A', 'Z'}; for (int i = 0; i < 4; ++i){ char c = chars[i]; REQUIRE(c == chars[i]); } } SECTION("Low ASCII"){ char null_terminator = '\0'; CHECK(null_terminator == '\0'); for (int i = 2; i < 6; ++i){ char c = static_cast(i); REQUIRE(c == i); } } } TEST_CASE( "Capture and info messages" ) { SECTION("Capture should stringify like assertions") { int i = 2; CAPTURE(i); REQUIRE(true); } SECTION("Info should NOT stringify the way assertions do") { int i = 3; INFO(i); REQUIRE(true); } } catch-1.12.1/projects/SelfTest/ToStringPair.cpp000066400000000000000000000032561325474075300213510ustar00rootroot00000000000000#include "catch.hpp" // === Pair === namespace Catch { // Note: If we put this in the right place in catch_tostring, then // we can make it an overload of Catch::toString template struct StringMaker > { static std::string convert( const std::pair& pair ) { std::ostringstream oss; oss << "{ " << toString( pair.first ) << ", " << toString( pair.second ) << " }"; return oss.str(); } }; } TEST_CASE( "std::pair -> toString", "[toString][pair]" ) { std::pair value( 34, "xyzzy" ); REQUIRE( Catch::toString( value ) == "{ 34, \"xyzzy\" }" ); } TEST_CASE( "std::pair -> toString", "[toString][pair]" ) { std::pair value( 34, "xyzzy" ); REQUIRE( Catch::toString(value) == "{ 34, \"xyzzy\" }" ); } TEST_CASE( "std::vector > -> toString", "[toString][pair]" ) { std::vector > pr; pr.push_back( std::make_pair("green", 55 ) ); REQUIRE( Catch::toString( pr ) == "{ { \"green\", 55 } }" ); } // This is pretty contrived - I figure if this works, anything will... TEST_CASE( "pair > -> toString", "[toString][pair]" ) { typedef std::pair left_t; typedef std::pair right_t; left_t left( 42, "Arthur" ); right_t right( "Ford", 24 ); std::pair pair( left, right ); REQUIRE( Catch::toString( pair ) == "{ { 42, \"Arthur\" }, { \"Ford\", 24 } }" ); } catch-1.12.1/projects/SelfTest/ToStringTuple.cpp000066400000000000000000000030761325474075300215470ustar00rootroot00000000000000#include "catch.hpp" #ifdef CATCH_CPP11_OR_GREATER #ifdef __clang__ #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wc++98-compat" #endif TEST_CASE( "tuple<>", "[toString][tuple][c++11][.]" ) { typedef std::tuple<> type; CHECK( "{ }" == Catch::toString(type{}) ); type value {}; CHECK( "{ }" == Catch::toString(value) ); } TEST_CASE( "tuple", "[toString][tuple][c++11][.]" ) { typedef std::tuple type; CHECK( "{ 0 }" == Catch::toString(type{0}) ); } TEST_CASE( "tuple", "[toString][tuple][c++11][.]" ) { typedef std::tuple type; CHECK( "1.2f" == Catch::toString(float(1.2)) ); CHECK( "{ 1.2f, 0 }" == Catch::toString(type{1.2,0}) ); } TEST_CASE( "tuple", "[toString][tuple][c++11][.]" ) { typedef std::tuple type; CHECK( "{ \"hello\", \"world\" }" == Catch::toString(type{"hello","world"}) ); } TEST_CASE( "tuple,tuple<>,float>", "[toString][tuple][c++11][.]" ) { typedef std::tuple,std::tuple<>,float> type; type value { std::tuple{42}, {}, 1.2f }; CHECK( "{ { 42 }, { }, 1.2f }" == Catch::toString(value) ); } #ifdef CATCH_CONFIG_CPP11_NULLPTR TEST_CASE( "tuple", "[toString][tuple][c++11][.]" ) { typedef std::tuple type; type value { nullptr, 42, "Catch me" }; CHECK( "{ nullptr, 42, \"Catch me\" }" == Catch::toString(value) ); } #endif #ifdef __clang__ #pragma clang diagnostic pop #endif #endif /* #ifdef CATCH_CPP11_OR_GREATER */ catch-1.12.1/projects/SelfTest/ToStringVector.cpp000066400000000000000000000045221325474075300217150ustar00rootroot00000000000000#include "catch.hpp" #include // vedctor TEST_CASE( "vector -> toString", "[toString][vector]" ) { std::vector vv; REQUIRE( Catch::toString(vv) == "{ }" ); vv.push_back( 42 ); REQUIRE( Catch::toString(vv) == "{ 42 }" ); vv.push_back( 250 ); REQUIRE( Catch::toString(vv) == "{ 42, 250 }" ); } TEST_CASE( "vector -> toString", "[toString][vector]" ) { std::vector vv; REQUIRE( Catch::toString(vv) == "{ }" ); vv.push_back( "hello" ); REQUIRE( Catch::toString(vv) == "{ \"hello\" }" ); vv.push_back( "world" ); REQUIRE( Catch::toString(vv) == "{ \"hello\", \"world\" }" ); } #if defined(CATCH_CPP11_OR_GREATER) #ifdef __clang__ #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wc++98-compat" #endif /* Note: These tests *can* be made to work with C++ < 11, but the allocator is a lot more work... */ namespace { /* Minimal Allocator */ template struct minimal_allocator { typedef T value_type; typedef std::size_t size_type; T *allocate( size_type n ) { return static_cast( ::operator new( n * sizeof(T) ) ); } void deallocate( T *p, size_type /*n*/ ) { ::operator delete( static_cast(p) ); } template bool operator==( const minimal_allocator& ) const { return true; } template bool operator!=( const minimal_allocator& ) const { return false; } }; } TEST_CASE( "vector -> toString", "[toString][vector,allocator][c++11][.]" ) { std::vector > vv; REQUIRE( Catch::toString(vv) == "{ }" ); vv.push_back( 42 ); REQUIRE( Catch::toString(vv) == "{ 42 }" ); vv.push_back( 250 ); REQUIRE( Catch::toString(vv) == "{ 42, 250 }" ); } TEST_CASE( "vec> -> toString", "[toString][vector,allocator][c++11][.]" ) { typedef std::vector > inner; typedef std::vector vector; vector v; REQUIRE( Catch::toString(v) == "{ }" ); v.push_back( inner { "hello" } ); v.push_back( inner { "world" } ); REQUIRE( Catch::toString(v) == "{ { \"hello\" }, { \"world\" } }" ); } #ifdef __clang__ #pragma clang diagnostic pop #endif #endif // CATCH_CPP11_OR_GREATER catch-1.12.1/projects/SelfTest/ToStringWhich.cpp000066400000000000000000000043251325474075300215160ustar00rootroot00000000000000#include "catch.hpp" /* Demonstrate which version of toString/StringMaker is being used for various types */ struct has_toString { }; struct has_maker {}; struct has_maker_and_toString {}; namespace Catch { inline std::string toString( const has_toString& ) { return "toString( has_toString )"; } inline std::string toString( const has_maker_and_toString& ) { return "toString( has_maker_and_toString )"; } template<> struct StringMaker { static std::string convert( const has_maker& ) { return "StringMaker"; } }; template<> struct StringMaker { static std::string convert( const has_maker_and_toString& ) { return "StringMaker"; } }; } // Call the overload TEST_CASE( "toString( has_toString )", "[toString]" ) { has_toString item; REQUIRE( Catch::toString( item ) == "toString( has_toString )" ); } // Call the overload TEST_CASE( "toString( has_maker )", "toString]" ) { has_maker item; REQUIRE( Catch::toString( item ) == "StringMaker" ); } // Call the overload TEST_CASE( "toString( has_maker_and_toString )", "[.][toString]" ) { has_maker_and_toString item; REQUIRE( Catch::toString( item ) == "toString( has_maker_and_toString )" ); } // Vectors... // Don't run this in approval tests as it is sensitive to two phase lookup differences TEST_CASE( "toString( vectors v(1); // This invokes template toString which actually gives us '{ ? }' REQUIRE( Catch::toString( v ) == "{ {?} }" ); } TEST_CASE( "toString( vectors v(1); REQUIRE( Catch::toString( v ) == "{ StringMaker }" ); } // Don't run this in approval tests as it is sensitive to two phase lookup differences TEST_CASE( "toString( vectors v(1); // Note: This invokes the template toString -> StringMaker REQUIRE( Catch::toString( v ) == "{ StringMaker }" ); } catch-1.12.1/projects/SelfTest/TrickyTests.cpp000066400000000000000000000206611325474075300212530ustar00rootroot00000000000000/* * Created by Phil on 09/11/2010. * Copyright 2010 Two Blue Cubes Ltd. All rights reserved. * * Distributed under the Boost Software License, Version 1.0. (See accompanying * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) */ #ifdef __clang__ #pragma clang diagnostic ignored "-Wpadded" #endif #include #include "catch.hpp" #ifdef __clang__ #pragma clang diagnostic ignored "-Wc++98-compat" #pragma clang diagnostic ignored "-Wc++98-compat-pedantic" #endif namespace Catch { template<> std::string toString >( const std::pair& value ) { std::ostringstream oss; oss << "std::pair( " << value.first << ", " << value.second << " )"; return oss.str(); } } /////////////////////////////////////////////////////////////////////////////// TEST_CASE ( "Parsing a std::pair", "[Tricky][std::pair]" ) { std::pair aNicePair( 1, 2 ); REQUIRE( (std::pair( 1, 2 )) == aNicePair ); } /////////////////////////////////////////////////////////////////////////////// TEST_CASE ( "Where there is more to the expression after the RHS", "[Tricky][failing][.]" ) { // int a = 1, b = 2; // REQUIRE( a == 2 || b == 2 ); WARN( "Uncomment the code in this test to check that it gives a sensible compiler error" ); } /////////////////////////////////////////////////////////////////////////////// TEST_CASE ( "Where the LHS is not a simple value", "[Tricky][failing][.]" ) { /* int a = 1; int b = 2; // This only captures part of the expression, but issues a warning about the rest REQUIRE( a+1 == b-1 ); */ WARN( "Uncomment the code in this test to check that it gives a sensible compiler error" ); } struct Opaque { int val; bool operator ==( const Opaque& o ) const { return val == o.val; } }; /////////////////////////////////////////////////////////////////////////////// TEST_CASE ( "A failing expression with a non streamable type is still captured", "[Tricky][failing][.]" ) { Opaque o1, o2; o1.val = 7; o2.val = 8; CHECK( &o1 == &o2 ); CHECK( o1 == o2 ); } /////////////////////////////////////////////////////////////////////////////// TEST_CASE ( "string literals of different sizes can be compared", "[Tricky][failing][.]" ) { REQUIRE( std::string( "first" ) == "second" ); } /////////////////////////////////////////////////////////////////////////////// TEST_CASE ( "An expression with side-effects should only be evaluated once", "[Tricky]" ) { int i = 7; REQUIRE( i++ == 7 ); REQUIRE( i++ == 8 ); } namespace A { struct X { X() : a(4), b(2), c(7) {} X(int v) : a(v), b(2), c(7) {} int a; int b; int c; }; } namespace B { struct Y { Y() : a(4), b(2), c(7) {} Y(int v) : a(v), b(2), c(7) {} int a; int b; int c; }; } inline bool operator==(const A::X& lhs, const B::Y& rhs) { return (lhs.a == rhs.a); } inline bool operator==(const B::Y& lhs, const A::X& rhs) { return (lhs.a == rhs.a); } /////////////////////////////////////////////////////////////////////////////// /* This, currently, does not compile with LLVM TEST_CASE ( "Operators at different namespace levels not hijacked by Koenig lookup" "[Tricky]" ) { A::X x; B::Y y; REQUIRE( x == y ); } */ namespace ObjectWithConversions { struct Object { operator unsigned int() {return 0xc0000000;} }; /////////////////////////////////////////////////////////////////////////////// TEST_CASE ( "Operators at different namespace levels not hijacked by Koenig lookup", "[Tricky]" ) { Object o; REQUIRE(0xc0000000 == o ); } } namespace ObjectWithNonConstEqualityOperator { struct Test { Test( unsigned int v ) : m_value(v) {} bool operator==( const Test&rhs ) { return (m_value == rhs.m_value); } bool operator==( const Test&rhs ) const { return (m_value != rhs.m_value); } unsigned int m_value; }; TEST_CASE("Demonstrate that a non-const == is not used", "[Tricky]" ) { Test t( 1 ); REQUIRE( t == 1u ); } } namespace EnumBitFieldTests { enum Bits {bit0 = 0x0001, bit1 = 0x0002, bit2 = 0x0004, bit3 = 0x0008, bit1and2 = 0x0006, bit30 = 0x40000000, bit31 = 0x80000000, bit30and31 = 0xc0000000}; TEST_CASE( "Test enum bit values", "[Tricky]" ) { REQUIRE( 0xc0000000 == bit30and31 ); } } struct Obj { Obj():prop(&p){} int p; int* prop; }; TEST_CASE("boolean member", "[Tricky]") { Obj obj; REQUIRE( obj.prop != CATCH_NULL ); } // Tests for a problem submitted by Ralph McArdell // // The static bool value should not need to be defined outside the // struct it is declared in - but when evaluating it in a deduced // context it appears to require the extra definition. // The issue was fixed by adding bool overloads to bypass the // templates that were there to deduce it. template struct is_true { static const bool value = B; }; TEST_CASE( "(unimplemented) static bools can be evaluated", "[Tricky]" ) { SECTION("compare to true","") { REQUIRE( is_true::value == true ); REQUIRE( true == is_true::value ); } SECTION("compare to false","") { REQUIRE( is_true::value == false ); REQUIRE( false == is_true::value ); } SECTION("negation", "") { REQUIRE( !is_true::value ); } SECTION("double negation","") { REQUIRE( !!is_true::value ); } SECTION("direct","") { REQUIRE( is_true::value ); REQUIRE_FALSE( is_true::value ); } } // Uncomment these tests to produce an error at test registration time /* TEST_CASE( "Tests with the same name are not allowed", "[Tricky]" ) { } TEST_CASE( "Tests with the same name are not allowed", "[Tricky]" ) { } */ struct Boolable { explicit Boolable( bool value ) : m_value( value ) {} operator Catch::SafeBool::type() const { return Catch::SafeBool::makeSafe( m_value ); } bool m_value; }; TEST_CASE( "Objects that evaluated in boolean contexts can be checked", "[Tricky][SafeBool]" ) { Boolable True( true ); Boolable False( false ); CHECK( True ); CHECK( !False ); CHECK_FALSE( False ); } TEST_CASE( "Assertions then sections", "[Tricky]" ) { // This was causing a failure due to the way the console reporter was handling // the current section REQUIRE( Catch::alwaysTrue() ); SECTION( "A section", "" ) { REQUIRE( Catch::alwaysTrue() ); SECTION( "Another section", "" ) { REQUIRE( Catch::alwaysTrue() ); } SECTION( "Another other section", "" ) { REQUIRE( Catch::alwaysTrue() ); } } } struct Awkward { operator int() const { return 7; } }; TEST_CASE( "non streamable - with conv. op", "[Tricky]" ) { Awkward awkward; std::string s = Catch::toString( awkward ); REQUIRE( s == "7" ); } inline void foo() {} typedef void (*fooptr_t)(); TEST_CASE( "Comparing function pointers", "[Tricky][function pointer]" ) { // This was giving a warning in VS2010 // #179 fooptr_t a = foo; REQUIRE( a ); REQUIRE( a == &foo ); } struct S { void f() {} }; TEST_CASE( "Comparing member function pointers", "[Tricky][member function pointer]" ) { typedef void (S::*MF)(); MF m = &S::f; CHECK( m == &S::f ); } class ClassName {}; TEST_CASE( "pointer to class", "[Tricky]" ) { ClassName *p = 0; REQUIRE( p == 0 ); } #ifdef CATCH_CONFIG_CPP11_NULLPTR #include TEST_CASE( "null_ptr", "[Tricky][c++11][.]" ) { std::unique_ptr ptr; REQUIRE(ptr.get() == nullptr); } #endif TEST_CASE( "X/level/0/a", "[Tricky]" ) { SUCCEED(""); } TEST_CASE( "X/level/0/b", "[Tricky][fizz]" ){ SUCCEED(""); } TEST_CASE( "X/level/1/a", "[Tricky]" ) { SUCCEED(""); } TEST_CASE( "X/level/1/b", "[Tricky]" ) { SUCCEED(""); } TEST_CASE( "has printf", "" ) { // This can cause problems as, currently, stdout itself is not redirect - only the cout (and cerr) buffer printf( "spanner" ); } TEST_CASE( "null deref", "[.][failing][!nonportable]" ) { CHECK( false ); int *x = NULL; *x = 1; } catch-1.12.1/projects/SelfTest/VariadicMacrosTests.cpp000066400000000000000000000011451325474075300226710ustar00rootroot00000000000000/* * Created by Phil on 15/03/2013. * Copyright 2013 Two Blue Cubes Ltd. All rights reserved. * * Distributed under the Boost Software License, Version 1.0. (See accompanying * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) */ #include "catch.hpp" #ifdef CATCH_CONFIG_VARIADIC_MACROS TEST_CASE() { SUCCEED( "anonymous test case" ); } TEST_CASE( "Test case with one argument" ) { SUCCEED( "no assertions" ); } TEST_CASE( "Variadic macros", "[variadic][sections]" ) { SECTION( "Section with one argument" ) { SUCCEED( "no assertions" ); } } #endif catch-1.12.1/projects/Where did the projects go.txt000066400000000000000000000016111325474075300220150ustar00rootroot00000000000000The canonical project format is now CMake. To generate an XCode or Visual Studio project you'll need CMake, which you can download from https://cmake.org if necessary. To generate the project files open a terminal/ console within the projects directory (where this file is located), create a directory called "Generated" (using mkdir or md), cd into it, then type: CMake -G ../.. Where is XCode for XCode projects, or "Visual Studio 14" for Visual Studio 2015 (replace 14 with the major version number for any other supported Visual Studio version - or execute CMake -help for the full list) Remember to re-run CMake any time you pull from GitHub. Note that the projects/Generated folder is excluded in .gitignore. So it is recommended to use this. CMake can also generate make files or projects for other build systems. Run CMake -help for the full set of options. catch-1.12.1/scripts/000077500000000000000000000000001325474075300143575ustar00rootroot00000000000000catch-1.12.1/scripts/approvalTests.py000077500000000000000000000130031325474075300176000ustar00rootroot00000000000000#!/usr/bin/env python from __future__ import print_function import os import sys import subprocess import re import difflib import scriptCommon from scriptCommon import catchPath rootPath = os.path.join(catchPath, 'projects/SelfTest/Baselines') filelocParser = re.compile(r''' .*/ (.+\.[ch]pp) # filename (?::|\() # : is starting separator between filename and line number on Linux, ( on Windows ([0-9]*) # line number \)? # Windows also has an ending separator, ) ''', re.VERBOSE) lineNumberParser = re.compile(r' line="[0-9]*"') hexParser = re.compile(r'\b(0[xX][0-9a-fA-F]+)\b') durationsParser = re.compile(r' time="[0-9]*\.[0-9]*"') timestampsParser = re.compile(r' timestamp="\d{4}-\d{2}-\d{2}T\d{2}\:\d{2}\:\d{2}Z"') versionParser = re.compile(r'Catch v[0-9]+\.[0-9]+\.[0-9]+(-develop\.[0-9]+)?') nullParser = re.compile(r'\b(__null|nullptr)\b') exeNameParser = re.compile(r''' \b (CatchSelfTest|SelfTest) # Expected executable name (?:.exe)? # Executable name contains .exe on Windows. \b ''', re.VERBOSE) # This is a hack until something more reasonable is figured out specialCaseParser = re.compile(r'file\((\d+)\)') # errno macro expands into various names depending on platform, so we need to fix them up as well errnoParser = re.compile(r''' \(\*__errno_location\ \(\)\) | \(\*__error\(\)\) ''', re.VERBOSE) if len(sys.argv) == 2: cmdPath = sys.argv[1] else: cmdPath = os.path.join(catchPath, scriptCommon.getBuildExecutable()) overallResult = 0 def diffFiles(fileA, fileB): with open(fileA, 'r') as file: aLines = [line.rstrip() for line in file.readlines()] with open(fileB, 'r') as file: bLines = [line.rstrip() for line in file.readlines()] shortenedFilenameA = fileA.rsplit(os.sep, 1)[-1] shortenedFilenameB = fileB.rsplit(os.sep, 1)[-1] diff = difflib.unified_diff(aLines, bLines, fromfile=shortenedFilenameA, tofile=shortenedFilenameB, n=0) return [line for line in diff if line[0] in ('+', '-')] def filterLine(line): if catchPath in line: # make paths relative to Catch root line = line.replace(catchPath + os.sep, '') # go from \ in windows paths to / line = line.replace('\\', '/') # strip source line numbers m = filelocParser.match(line) if m: # note that this also strips directories, leaving only the filename filename, lnum = m.groups() lnum = ":" if lnum else "" line = filename + lnum + line[m.end():] else: line = lineNumberParser.sub(" ", line) # strip Catch version number line = versionParser.sub("", line) # replace *null* with 0 line = nullParser.sub("0", line) # strip executable name line = exeNameParser.sub("", line) # strip hexadecimal numbers (presumably pointer values) line = hexParser.sub("0x", line) # strip durations and timestamps line = durationsParser.sub(' time="{duration}"', line) line = timestampsParser.sub(' timestamp="{iso8601-timestamp}"', line) line = specialCaseParser.sub('file:\g<1>', line) line = errnoParser.sub('errno', line) return line def approve(baseName, args): global overallResult args[0:0] = [cmdPath] if not os.path.exists(cmdPath): raise Exception("Executable doesn't exist at " + cmdPath) baselinesPath = os.path.join(rootPath, '{0}.approved.txt'.format(baseName)) rawResultsPath = os.path.join(rootPath, '_{0}.tmp'.format(baseName)) filteredResultsPath = os.path.join(rootPath, '{0}.unapproved.txt'.format(baseName)) f = open(rawResultsPath, 'w') subprocess.call(args, stdout=f, stderr=f) f.close() rawFile = open(rawResultsPath, 'r') filteredFile = open(filteredResultsPath, 'w') for line in rawFile: filteredFile.write(filterLine(line).rstrip() + "\n") filteredFile.close() rawFile.close() os.remove(rawResultsPath) print() print(baseName + ":") if os.path.exists(baselinesPath): diffResult = diffFiles(baselinesPath, filteredResultsPath) if diffResult: print('\n'.join(diffResult)) print(" \n****************************\n \033[91mResults differed") if len(diffResult) > overallResult: overallResult = len(diffResult) else: os.remove(filteredResultsPath) print(" \033[92mResults matched") print("\033[0m") else: print(" first approval") if overallResult == 0: overallResult = 1 print("Running approvals against executable:") print(" " + cmdPath) # Standard console reporter approve("console.std", ["~[c++11]~[!nonportable]", "--order", "lex"]) # console reporter, include passes, warn about No Assertions approve("console.sw", ["~[c++11]~[!nonportable]", "-s", "-w", "NoAssertions", "--order", "lex"]) # console reporter, include passes, warn about No Assertions, limit failures to first 4 approve("console.swa4", ["~[c++11]~[!nonportable]", "-s", "-w", "NoAssertions", "-x", "4", "--order", "lex"]) # junit reporter, include passes, warn about No Assertions approve("junit.sw", ["~[c++11]~[!nonportable]", "-s", "-w", "NoAssertions", "-r", "junit", "--order", "lex"]) # xml reporter, include passes, warn about No Assertions approve("xml.sw", ["~[c++11]~[!nonportable]", "-s", "-w", "NoAssertions", "-r", "xml", "--order", "lex"]) if overallResult != 0: print("If these differences are expected, run approve.py to approve new baselines.") exit(overallResult) catch-1.12.1/scripts/approve.py000077500000000000000000000016141325474075300164120ustar00rootroot00000000000000#!/usr/bin/env python from __future__ import print_function import os import sys import shutil import glob from scriptCommon import catchPath rootPath = os.path.join( catchPath, 'projects/SelfTest/Baselines' ) if len(sys.argv) > 1: files = [os.path.join( rootPath, f ) for f in sys.argv[1:]] else: files = glob.glob( os.path.join( rootPath, "*.unapproved.txt" ) ) def approveFile( approvedFile, unapprovedFile ): justFilename = unapprovedFile[len(rootPath)+1:] if os.path.exists( unapprovedFile ): if os.path.exists( approvedFile ): os.remove( approvedFile ) os.rename( unapprovedFile, approvedFile ) print( "approved " + justFilename ) else: print( "approval file " + justFilename + " does not exist" ) if len(files) > 0: for unapprovedFile in files: approveFile( unapprovedFile.replace( "unapproved.txt", "approved.txt" ), unapprovedFile ) else: print( "no files to approve" ) catch-1.12.1/scripts/benchmarkCompile.py000077500000000000000000000110041325474075300201730ustar00rootroot00000000000000#!/usr/bin/env python from __future__ import print_function import time, subprocess, sys, os, shutil, glob, random import argparse def median(lst): lst = sorted(lst) mid, odd = divmod(len(lst), 2) if odd: return lst[mid] else: return (lst[mid - 1] + lst[mid]) / 2.0 def mean(lst): return float(sum(lst)) / max(len(lst), 1) compiler_path = '' flags = [] main_file = r''' #define CATCH_CONFIG_MAIN #include "catch.hpp" ''' main_name = 'catch-main.cpp' dir_name = 'benchmark-dir' files = 20 test_cases_in_file = 20 sections_in_file = 4 assertions_per_section = 5 checks = [ 'a != b', 'a != c', 'a != d', 'a != e', 'b != c', 'b != d', 'b != e', 'c != d', 'c != e', 'd != e', 'a + a == a', 'a + b == b', 'a + c == c', 'a + d == d', 'a + e == e', 'b + a == b', 'b + b == c', 'b + c == d', 'b + d == e', 'c + a == c', 'c + b == d', 'c + c == e', 'd + a == d', 'd + b == e', 'e + a == e', 'a + a + a == a', 'b + c == a + d', 'c + a + a == a + b + b + a', 'a < b', 'b < c', 'c < d', 'd < e', 'a >= a', 'd >= b', ] def create_temp_dir(): if os.path.exists(dir_name): shutil.rmtree(dir_name) os.mkdir(dir_name) def copy_catch(path_to_catch): shutil.copy(path_to_catch, dir_name) def create_catch_main(): with open(main_name, 'w') as f: f.write(main_file) def compile_main(): start_t = time.time() subprocess.check_call([compiler_path, main_name, '-c'] + flags) end_t = time.time() return end_t - start_t def compile_files(): cpp_files = glob.glob('*.cpp') start_t = time.time() subprocess.check_call([compiler_path, '-c'] + flags + cpp_files) end_t = time.time() return end_t - start_t def link_files(): obj_files = glob.glob('*.o') start_t = time.time() subprocess.check_call([compiler_path] + flags + obj_files) end_t = time.time() return end_t - start_t def benchmark(func): results = [func() for i in range(10)] return mean(results), median(results) def char_range(start, end): for c in range(ord(start), ord(end)): yield chr(c) def generate_sections(fd): for i in range(sections_in_file): fd.write(' SECTION("Section {}") {{\n'.format(i)) fd.write('\n'.join(' CHECK({});'.format(check) for check in random.sample(checks, assertions_per_section))) fd.write(' }\n') def generate_file(file_no): with open('tests{}.cpp'.format(file_no), 'w') as f: f.write('#include "catch.hpp"\n\n') for i in range(test_cases_in_file): f.write('TEST_CASE("File {} test {}", "[.compile]"){{\n'.format(file_no, i)) for i, c in enumerate(char_range('a', 'f')): f.write(' int {} = {};\n'.format(c, i)) generate_sections(f) f.write('}\n\n') def generate_files(): create_catch_main() for i in range(files): generate_file(i) options = ['all', 'main', 'files', 'link'] parser = argparse.ArgumentParser(description='Benchmarks Catch\'s compile times against some synthetic tests') # Add first arg -- benchmark type parser.add_argument('benchmark_kind', nargs='?', default='all', choices=options, help='What kind of benchmark to run, default: all') # Args to allow changing header/compiler parser.add_argument('-I', '--catch-header', default='catch.hpp', help = 'Path to catch.hpp, default: catch.hpp') parser.add_argument('-c', '--compiler', default='g++', help = 'Compiler to use, default: g++') parser.add_argument('-f', '--flags', nargs='*', help = 'Flags to be passed to the compiler') # Allow creating files only, without running the whole thing parser.add_argument('-g', '--generate-files', action='store_true', help='Generate test files and quit') args = parser.parse_args() compiler_path = args.compiler catch_path = args.catch_header if args.generate_files: create_temp_dir() copy_catch(catch_path) os.chdir(dir_name) # now create the fake test files generate_files() # Early exit print('Finished generating files') exit(1) os.chdir(dir_name) if args.flags: flags = args.flags print('Time needed for ...') if args.benchmark_kind in ('all', 'main'): print(' ... compiling main, mean: {:.2f}, median: {:.2f} s'.format(*benchmark(compile_main))) if args.benchmark_kind in ('all', 'files'): print(' ... compiling test files, mean: {:.2f}, median: {:.2f} s'.format(*benchmark(compile_files))) if args.benchmark_kind in ('all', 'link'): print(' ... linking everything, mean: {:.2f}, median: {:.2f} s'.format(*benchmark(link_files))) catch-1.12.1/scripts/benchmarkRunner.py000077500000000000000000000031401325474075300200560ustar00rootroot00000000000000#!/usr/bin/env python3 import subprocess, os, sys import xml.etree.ElementTree as ET from collections import defaultdict from statistics import median, stdev from datetime import datetime def get_commit_hash(): res = subprocess.run('git rev-parse HEAD'.split(), check=True, stdout=subprocess.PIPE, universal_newlines=True) return res.stdout.strip() if len(sys.argv) < 2: print('Usage: {} benchmark-binary'.format(sys.argv[0])) exit(1) num_runs = 10 data = defaultdict(list) def parse_file(file): def recursive_search(node): if node.tag == 'TestCase': results = node.find('OverallResult') time = results.get('durationInSeconds') data[node.get('name')].append(float(time)) elif node.tag in ('Group', 'Catch'): for child in node: recursive_search(child) tree = ET.parse(file) recursive_search(tree.getroot()) def run_benchmarks(binary): call = [binary] + '-d yes -r xml -o'.split() for i in range(num_runs): file = 'temp{}.xml'.format(i) print('Run number {}'.format(i)) subprocess.run(call + [file]) parse_file(file) # Remove file right after parsing, because benchmark output can be big os.remove(file) # Run benchmarks run_benchmarks(sys.argv[1]) result_file = '{:%Y-%m-%dT%H-%M-%S}-{}.result'.format(datetime.now(), get_commit_hash()) print('Writing results to {}'.format(result_file)) with open(result_file, 'w') as file: for k in sorted(data): file.write('{}: median: {} (s), stddev: {} (s)\n'.format(k, median(data[k]), stdev(data[k]))) catch-1.12.1/scripts/developBuild.py000077500000000000000000000004711325474075300173540ustar00rootroot00000000000000#!/usr/bin/env python from __future__ import print_function from releaseCommon import Version v = Version() v.incrementBuildNumber() v.updateVersionFile() v.updateReadmeFile() v.updateConanFile() v.updateConanTestFile() print( "Updated Version.hpp, README and Conan to v{0}".format( v.getVersionString() ) ) catch-1.12.1/scripts/fixWhitespace.py000077500000000000000000000024471325474075300175460ustar00rootroot00000000000000#!/usr/bin/env python from __future__ import print_function import os from scriptCommon import catchPath changedFiles = 0 def isSourceFile( path ): return path.endswith( ".cpp" ) or path.endswith( ".h" ) or path.endswith( ".hpp" ) def fixAllFilesInDir( dir ): for f in os.listdir( dir ): path = os.path.join( dir,f ) if os.path.isfile( path ): if isSourceFile( path ): fixFile( path ) else: fixAllFilesInDir( path ) def fixFile( path ): f = open( path, 'r' ) lines = [] changed = 0 for line in f: trimmed = line.rstrip() + "\n" trimmed = trimmed.replace('\t', ' ') if trimmed != line: changed = changed +1 lines.append( trimmed ) f.close() if changed > 0: global changedFiles changedFiles = changedFiles + 1 print( path + ":" ) print( " - fixed " + str(changed) + " line(s)" ) altPath = path + ".backup" os.rename( path, altPath ) f2 = open( path, 'w' ) for line in lines: f2.write( line ) f2.close() os.remove( altPath ) fixAllFilesInDir(catchPath) if changedFiles > 0: print( "Fixed " + str(changedFiles) + " file(s)" ) else: print( "No trailing whitespace found" ) catch-1.12.1/scripts/generateSingleHeader.py000077500000000000000000000103211325474075300207760ustar00rootroot00000000000000#!/usr/bin/env python from __future__ import print_function import os import sys import re import datetime import string from scriptCommon import catchPath def generate(v): includesParser = re.compile( r'\s*#\s*include\s*"(.*)"' ) guardParser = re.compile( r'\s*#.*TWOBLUECUBES_CATCH_.*_INCLUDED') defineParser = re.compile( r'\s*#define') ifParser = re.compile( r'\s*#ifndef TWOBLUECUBES_CATCH_.*_INCLUDED') endIfParser = re.compile( r'\s*#endif // TWOBLUECUBES_CATCH_.*_INCLUDED') ifImplParser = re.compile( r'\s*#ifdef CATCH_CONFIG_RUNNER' ) commentParser1 = re.compile( r'^\s*/\*') commentParser2 = re.compile( r'^ \*') blankParser = re.compile( r'^\s*$') seenHeaders = set([]) rootPath = os.path.join( catchPath, 'include/' ) outputPath = os.path.join( catchPath, 'single_include/catch.hpp' ) globals = { 'ifdefs' : 0, 'implIfDefs' : -1, 'includeImpl': True } for arg in sys.argv[1:]: arg = string.lower(arg) if arg == "noimpl": globals['includeImpl'] = False print( "Not including impl code" ) else: print( "\n** Unrecognised argument: " + arg + " **\n" ) exit(1) out = open( outputPath, 'w' ) def write( line ): if globals['includeImpl'] or globals['implIfDefs'] == -1: out.write( line ) def parseFile( path, filename ): f = open( path + filename, 'r' ) blanks = 0 for line in f: if ifParser.match( line ): globals['ifdefs'] += 1 elif endIfParser.match( line ): globals['ifdefs'] -= 1 if globals['ifdefs'] == globals['implIfDefs']: globals['implIfDefs'] = -1 m = includesParser.match( line ) if m: header = m.group(1) headerPath, sep, headerFile = header.rpartition( "/" ) if not headerFile in seenHeaders: if headerFile != "tbc_text_format.h" and headerFile != "clara.h": seenHeaders.add( headerFile ) write( "// #included from: {0}\n".format( header ) ) if headerPath == "internal" and path.endswith("internal/"): headerPath = "" sep = "" if os.path.exists( path + headerPath + sep + headerFile ): parseFile( path + headerPath + sep, headerFile ) else: parseFile( rootPath + headerPath + sep, headerFile ) else: if ifImplParser.match(line): globals['implIfDefs'] = globals['ifdefs'] if (not guardParser.match( line ) or defineParser.match( line ) ) and not commentParser1.match( line )and not commentParser2.match( line ): if blankParser.match( line ): blanks = blanks + 1 else: blanks = 0 if blanks < 2: write( line.rstrip() + "\n" ) out.write( "/*\n" ) out.write( " * Catch v{0}\n".format( v.getVersionString() ) ) out.write( " * Generated: {0}\n".format( datetime.datetime.now() ) ) out.write( " * ----------------------------------------------------------\n" ) out.write( " * This file has been merged from multiple headers. Please don't edit it directly\n" ) out.write( " * Copyright (c) 2012 Two Blue Cubes Ltd. All rights reserved.\n" ) out.write( " *\n" ) out.write( " * Distributed under the Boost Software License, Version 1.0. (See accompanying\n" ) out.write( " * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)\n" ) out.write( " */\n" ) out.write( "#ifndef TWOBLUECUBES_SINGLE_INCLUDE_CATCH_HPP_INCLUDED\n" ) out.write( "#define TWOBLUECUBES_SINGLE_INCLUDE_CATCH_HPP_INCLUDED\n" ) parseFile( rootPath, 'catch.hpp' ) out.write( "#endif // TWOBLUECUBES_SINGLE_INCLUDE_CATCH_HPP_INCLUDED\n\n" ) out.close() print ("Generated single include for Catch v{0}\n".format( v.getVersionString() ) ) if __name__ == '__main__': from releaseCommon import Version generate(Version()) catch-1.12.1/scripts/majorRelease.py000077500000000000000000000004041325474075300173430ustar00rootroot00000000000000#!/usr/bin/env python from __future__ import print_function import releaseCommon v = releaseCommon.Version() v.incrementMajorVersion() releaseCommon.performUpdates(v) print( "Updated Version.hpp, README and Conan to v{0}".format( v.getVersionString() ) ) catch-1.12.1/scripts/minorRelease.py000077500000000000000000000004041325474075300173570ustar00rootroot00000000000000#!/usr/bin/env python from __future__ import print_function import releaseCommon v = releaseCommon.Version() v.incrementMinorVersion() releaseCommon.performUpdates(v) print( "Updated Version.hpp, README and Conan to v{0}".format( v.getVersionString() ) ) catch-1.12.1/scripts/patchRelease.py000077500000000000000000000004031325474075300173310ustar00rootroot00000000000000#!/usr/bin/env python from __future__ import print_function import releaseCommon v = releaseCommon.Version() v.incrementPatchNumber() releaseCommon.performUpdates(v) print( "Updated Version.hpp, README and Conan to v{0}".format( v.getVersionString() ) ) catch-1.12.1/scripts/releaseCommon.py000066400000000000000000000116251325474075300175270ustar00rootroot00000000000000from __future__ import print_function import os import sys import re import string from scriptCommon import catchPath import generateSingleHeader import updateWandbox versionParser = re.compile( r'(\s*static\sVersion\sversion)\s*\(\s*(.*)\s*,\s*(.*)\s*,\s*(.*)\s*,\s*\"(.*)\"\s*,\s*(.*)\s*\).*' ) rootPath = os.path.join( catchPath, 'include/' ) versionPath = os.path.join( rootPath, "internal/catch_version.hpp" ) readmePath = os.path.join( catchPath, "README.md" ) conanPath = os.path.join(catchPath, 'conanfile.py') conanTestPath = os.path.join(catchPath, 'test_package', 'conanfile.py') class Version: def __init__(self): f = open( versionPath, 'r' ) for line in f: m = versionParser.match( line ) if m: self.variableDecl = m.group(1) self.majorVersion = int(m.group(2)) self.minorVersion = int(m.group(3)) self.patchNumber = int(m.group(4)) self.branchName = m.group(5) self.buildNumber = int(m.group(6)) f.close() def nonDevelopRelease(self): if self.branchName != "": self.branchName = "" self.buildNumber = 0 def developBuild(self): if self.branchName == "": self.branchName = "develop" self.buildNumber = 0 def incrementBuildNumber(self): self.developBuild() self.buildNumber = self.buildNumber+1 def incrementPatchNumber(self): self.nonDevelopRelease() self.patchNumber = self.patchNumber+1 def incrementMinorVersion(self): self.nonDevelopRelease() self.patchNumber = 0 self.minorVersion = self.minorVersion+1 def incrementMajorVersion(self): self.nonDevelopRelease() self.patchNumber = 0 self.minorVersion = 0 self.majorVersion = self.majorVersion+1 def getVersionString(self): versionString = '{0}.{1}.{2}'.format( self.majorVersion, self.minorVersion, self.patchNumber ) if self.branchName != "": versionString = versionString + '-{0}.{1}'.format( self.branchName, self.buildNumber ) return versionString def updateVersionFile(self): f = open( versionPath, 'r' ) lines = [] for line in f: m = versionParser.match( line ) if m: lines.append( '{0}( {1}, {2}, {3}, "{4}", {5} );'.format( self.variableDecl, self.majorVersion, self.minorVersion, self.patchNumber, self.branchName, self.buildNumber ) ) else: lines.append( line.rstrip() ) f.close() f = open( versionPath, 'w' ) for line in lines: f.write( line + "\n" ) def updateReadmeFile(version): downloadParser = re.compile( r'' ) 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: lines.append( line.rstrip() ) f.close() f = open( readmePath, 'w' ) for line in lines: line = downloadParser.sub( r''.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) f.write( line + "\n" ) def updateConanFile(version): conanParser = re.compile( r' version = "\d+\.\d+\.\d+.*"') f = open( conanPath, 'r' ) lines = [] for line in f: m = conanParser.match( line ) if m: lines.append( ' version = "{0}"'.format(format(version.getVersionString())) ) else: lines.append( line.rstrip() ) f.close() f = open( conanPath, 'w' ) for line in lines: f.write( line + "\n" ) def updateConanTestFile(version): conanParser = re.compile( r' requires = \"Catch\/\d+\.\d+\.\d+.*@%s\/%s\" % \(username, channel\)') f = open( conanTestPath, 'r' ) lines = [] for line in f: m = conanParser.match( line ) if m: lines.append( ' requires = "Catch/{0}@%s/%s" % (username, channel)'.format(format(version.getVersionString())) ) else: lines.append( line.rstrip() ) f.close() f = open( conanTestPath, 'w' ) for line in lines: f.write( line + "\n" ) def performUpdates(version): # First update version file, so we can regenerate single header and # have it ready for upload to wandbox, when updating readme version.updateVersionFile() # ToDo: Regenerate single header generateSingleHeader.generate(version) updateReadmeFile(version) updateConanFile(version) updateConanTestFile(version) catch-1.12.1/scripts/releaseNotes.py000077500000000000000000000032251325474075300173670ustar00rootroot00000000000000#!/usr/bin/env python import os import re import urllib2 import json from scriptCommon import catchPath from scriptCommon import runAndCapture issueNumberRe = re.compile( r'(.*?)#([0-9]*)([^0-9]?.*)' ) rootPath = os.path.join( catchPath, 'include/' ) versionPath = os.path.join( rootPath, "internal/catch_version.hpp" ) hashes = runAndCapture( ['git', 'log', '-2', '--format="%H"', versionPath] ) lines = runAndCapture( ['git', 'log', hashes[1] + ".." + hashes[0], catchPath] ) prevLine = "" messages = [] dates = [] issues = {} def getIssueTitle( issueNumber ): try: s = urllib2.urlopen("https://api.github.com/repos/philsquared/catch/issues/" + issueNumber ).read() except: return "#HTTP Error#" try: j = json.loads( s ) return j["title"] except: return "#JSON Error#" for line in lines: if line.startswith( "commit"): pass elif line.startswith( "Author:"): pass elif line.startswith( "Date:"): dates.append( line[5:].lstrip() ) pass elif line == "" and prevLine == "": pass else: prevLine = line match = issueNumberRe.match( line ) line2 = "" while match: issueNumber = match.group(2) issue = '#{0} ("{1}")'.format( issueNumber, getIssueTitle( issueNumber ) ) line2 = line2 + match.group(1) + issue match = issueNumberRe.match( match.group(3) ) if line2 == "": messages.append( line ) else: messages.append( line2 ) print "All changes between {0} and {1}:\n".format( dates[-1], dates[0] ) for line in messages: print line catch-1.12.1/scripts/scriptCommon.py000066400000000000000000000012421325474075300174050ustar00rootroot00000000000000import os import sys import subprocess catchPath = os.path.dirname(os.path.realpath( os.path.dirname(sys.argv[0]))) def getBuildExecutable(): dir = os.environ.get('CATCH_DEV_OUT_DIR', "cmake-build-debug/SelfTest") return dir def runAndCapture( args ): child = subprocess.Popen(" ".join( args ), shell=True, stdout=subprocess.PIPE) lines = [] line = "" while True: out = child.stdout.read(1) if out == '' and child.poll() != None: break if out != '': if out == '\n': lines.append( line ) line = "" else: line = line + out return lines catch-1.12.1/scripts/updateVcpkgPackage.py000066400000000000000000000071251325474075300204670ustar00rootroot00000000000000#!/usr/bin/env python import io, os, re, sys, subprocess import hashlib from scriptCommon import catchPath from releaseCommon import Version print(catchPath) default_path = '../vcpkg/ports/catch-classic/' def adjusted_path(path): return os.path.join(catchPath, path) def get_hash(path): BUFF_SIZE = 65536 sha512 = hashlib.sha512() # The newlines should be normalized into \n, which is what we want # If reused use 'rb' with a file written with io.open(newline='\n') with open(path, 'r') as f: while True: data = f.read(BUFF_SIZE) if not data: break if sys.version_info[0] < 3: sha512.update(data) else: sha512.update(data.encode('utf-8')) return sha512.hexdigest() def update_control(path): v = Version() ver_string = v.getVersionString() # Update control lines = [] control_path = os.path.join(path, 'CONTROL') with open(control_path, 'r') as f: for line in f: lines.append(line) with open(control_path, 'w') as f: for line in lines: if 'Version: ' in line: line = 'Version: {}\n'.format(v.getVersionString()) f.write(line) def update_portfile(path, header_hash, licence_hash): print('Updating portfile') v = Version() ver_string = v.getVersionString() # Update portfile lines = [] portfile_path = os.path.join(path, 'portfile.cmake') with open(portfile_path, 'r') as f: for line in f: lines.append(line) with open(portfile_path, 'w') as f: # There are three things we need to change/update # 1) CATCH_VERSION cmake variable # 2) Hash of header # 3) Hash of licence # We could assume licence never changes, but where is the fun in that? for line in lines: # Update the version if 'set(CATCH_VERSION' in line: line = 'set(CATCH_VERSION v{})\n'.format(v.getVersionString()) # Determine which file we are updating if 'vcpkg_download_distfile' in line: kind = line.split('(')[-1].strip() # Update the hashes if 'SHA512' in line and kind == 'HEADER': line = ' SHA512 {}\n'.format(header_hash) if 'SHA512' in line and kind == 'LICENSE': line = ' SHA512 {}\n'.format(licence_hash) f.write(line) def git_push(path_to_repo): v = Version() ver_string = v.getVersionString() os.chdir(path_to_repo) # Work with git # 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 subprocess.call('git pull Microsoft master', shell=True) subprocess.call('git push', shell=True) # Create a new branch for the update subprocess.call('git checkout -b catch-{}'.format(ver_string), shell=True) # Add changed files (should be only our files) subprocess.call('git add -u .', shell=True) # Create a commit with these changes subprocess.call('git commit -m "Update Catch to {}"'.format(ver_string), shell=True) # Don't push, so author can review print('Changes were commited to the vcpkg fork. Please check, push and open PR.') header_hash = get_hash(adjusted_path('single_include/catch.hpp')) licence_hash = get_hash(adjusted_path('LICENSE.txt')) update_control(adjusted_path(default_path)) update_portfile(adjusted_path(default_path), header_hash, licence_hash) git_push(adjusted_path('../vcpkg')) catch-1.12.1/scripts/updateWandbox.py000066400000000000000000000025151325474075300175410ustar00rootroot00000000000000#!/usr/bin/env python import json import os import urllib2 from scriptCommon import catchPath def upload(options): request = urllib2.Request('http://melpon.org/wandbox/api/compile.json') request.add_header('Content-Type', 'application/json') response = urllib2.urlopen(request, json.dumps(options)) return json.loads(response.read()) main_file = ''' #define CATCH_CONFIG_MAIN // This tells Catch to provide a main() - only do this in one cpp file #include "catch.hpp" unsigned int Factorial( unsigned int number ) { return number <= 1 ? number : Factorial(number-1)*number; } TEST_CASE( "Factorials are computed", "[factorial]" ) { REQUIRE( Factorial(1) == 1 ); REQUIRE( Factorial(2) == 2 ); REQUIRE( Factorial(3) == 6 ); REQUIRE( Factorial(10) == 3628800 ); } ''' def uploadFiles(): response = upload({ 'compiler': 'gcc-head', 'code': main_file, 'codes': [{ 'file': 'catch.hpp', 'code': open(os.path.join(catchPath, 'single_include', 'catch.hpp')).read() }], 'options': 'c++11,cpp-no-pedantic,boost-nothing', 'compiler-option-raw': '-DCATCH_CONFIG_FAST_COMPILE', 'save': True }) if 'status' in response and not 'compiler_error' in response: return True, response['url'] else: return False, response catch-1.12.1/single_include/000077500000000000000000000000001325474075300156545ustar00rootroot00000000000000catch-1.12.1/single_include/catch.hpp000066400000000000000000015002621325474075300174550ustar00rootroot00000000000000/* * Catch v1.12.1 * Generated: 2018-03-02 21:17:41.036711 * ---------------------------------------------------------- * This file has been merged from multiple headers. Please don't edit it directly * Copyright (c) 2012 Two Blue Cubes Ltd. All rights reserved. * * Distributed under the Boost Software License, Version 1.0. (See accompanying * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) */ #ifndef TWOBLUECUBES_SINGLE_INCLUDE_CATCH_HPP_INCLUDED #define TWOBLUECUBES_SINGLE_INCLUDE_CATCH_HPP_INCLUDED #define TWOBLUECUBES_CATCH_HPP_INCLUDED #ifdef __clang__ # pragma clang system_header #elif defined __GNUC__ # pragma GCC system_header #endif // #included from: internal/catch_suppress_warnings.h #ifdef __clang__ # ifdef __ICC // icpc defines the __clang__ macro # pragma warning(push) # pragma warning(disable: 161 1682) # else // __ICC # pragma clang diagnostic ignored "-Wglobal-constructors" # pragma clang diagnostic ignored "-Wvariadic-macros" # pragma clang diagnostic ignored "-Wc99-extensions" # pragma clang diagnostic ignored "-Wunused-variable" # pragma clang diagnostic push # pragma clang diagnostic ignored "-Wpadded" # pragma clang diagnostic ignored "-Wc++98-compat" # pragma clang diagnostic ignored "-Wc++98-compat-pedantic" # pragma clang diagnostic ignored "-Wswitch-enum" # pragma clang diagnostic ignored "-Wcovered-switch-default" # endif #elif defined __GNUC__ # pragma GCC diagnostic ignored "-Wvariadic-macros" # pragma GCC diagnostic ignored "-Wunused-variable" # pragma GCC diagnostic ignored "-Wparentheses" # pragma GCC diagnostic push # pragma GCC diagnostic ignored "-Wpadded" #endif #if defined(CATCH_CONFIG_MAIN) || defined(CATCH_CONFIG_RUNNER) # define CATCH_IMPL #endif #ifdef CATCH_IMPL # ifndef CLARA_CONFIG_MAIN # define CLARA_CONFIG_MAIN_NOT_DEFINED # define CLARA_CONFIG_MAIN # endif #endif // #included from: internal/catch_notimplemented_exception.h #define TWOBLUECUBES_CATCH_NOTIMPLEMENTED_EXCEPTION_H_INCLUDED // #included from: catch_common.h #define TWOBLUECUBES_CATCH_COMMON_H_INCLUDED // #included from: catch_compiler_capabilities.h #define TWOBLUECUBES_CATCH_COMPILER_CAPABILITIES_HPP_INCLUDED // Detect a number of compiler features - mostly C++11/14 conformance - by compiler // The following features are defined: // // CATCH_CONFIG_CPP11_NULLPTR : is nullptr supported? // CATCH_CONFIG_CPP11_NOEXCEPT : is noexcept supported? // CATCH_CONFIG_CPP11_GENERATED_METHODS : The delete and default keywords for compiler generated methods // CATCH_CONFIG_CPP11_IS_ENUM : std::is_enum is supported? // CATCH_CONFIG_CPP11_TUPLE : std::tuple is supported // CATCH_CONFIG_CPP11_LONG_LONG : is long long supported? // CATCH_CONFIG_CPP11_OVERRIDE : is override supported? // CATCH_CONFIG_CPP11_UNIQUE_PTR : is unique_ptr supported (otherwise use auto_ptr) // CATCH_CONFIG_CPP11_SHUFFLE : is std::shuffle supported? // CATCH_CONFIG_CPP11_TYPE_TRAITS : are type_traits and enable_if supported? // CATCH_CONFIG_CPP11_OR_GREATER : Is C++11 supported? // CATCH_CONFIG_VARIADIC_MACROS : are variadic macros supported? // CATCH_CONFIG_COUNTER : is the __COUNTER__ macro supported? // CATCH_CONFIG_WINDOWS_SEH : is Windows SEH supported? // CATCH_CONFIG_POSIX_SIGNALS : are POSIX signals supported? // **************** // Note to maintainers: if new toggles are added please document them // in configuration.md, too // **************** // In general each macro has a _NO_ form // (e.g. CATCH_CONFIG_CPP11_NO_NULLPTR) which disables the feature. // Many features, at point of detection, define an _INTERNAL_ macro, so they // can be combined, en-mass, with the _NO_ forms later. // All the C++11 features can be disabled with CATCH_CONFIG_NO_CPP11 #ifdef __cplusplus # if __cplusplus >= 201103L # define CATCH_CPP11_OR_GREATER # endif # if __cplusplus >= 201402L # define CATCH_CPP14_OR_GREATER # endif #endif #ifdef __clang__ # if __has_feature(cxx_nullptr) # define CATCH_INTERNAL_CONFIG_CPP11_NULLPTR # endif # if __has_feature(cxx_noexcept) # define CATCH_INTERNAL_CONFIG_CPP11_NOEXCEPT # endif # if defined(CATCH_CPP11_OR_GREATER) # define CATCH_INTERNAL_SUPPRESS_ETD_WARNINGS \ _Pragma( "clang diagnostic push" ) \ _Pragma( "clang diagnostic ignored \"-Wexit-time-destructors\"" ) # define CATCH_INTERNAL_UNSUPPRESS_ETD_WARNINGS \ _Pragma( "clang diagnostic pop" ) # define CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS \ _Pragma( "clang diagnostic push" ) \ _Pragma( "clang diagnostic ignored \"-Wparentheses\"" ) # define CATCH_INTERNAL_UNSUPPRESS_PARENTHESES_WARNINGS \ _Pragma( "clang diagnostic pop" ) # endif #endif // __clang__ //////////////////////////////////////////////////////////////////////////////// // We know some environments not to support full POSIX signals #if defined(__CYGWIN__) || defined(__QNX__) # if !defined(CATCH_CONFIG_POSIX_SIGNALS) # define CATCH_INTERNAL_CONFIG_NO_POSIX_SIGNALS # endif #endif #ifdef __OS400__ # define CATCH_INTERNAL_CONFIG_NO_POSIX_SIGNALS # define CATCH_CONFIG_COLOUR_NONE #endif //////////////////////////////////////////////////////////////////////////////// // Cygwin #ifdef __CYGWIN__ // Required for some versions of Cygwin to declare gettimeofday // see: http://stackoverflow.com/questions/36901803/gettimeofday-not-declared-in-this-scope-cygwin # define _BSD_SOURCE #endif // __CYGWIN__ //////////////////////////////////////////////////////////////////////////////// // Borland #ifdef __BORLANDC__ #endif // __BORLANDC__ //////////////////////////////////////////////////////////////////////////////// // EDG #ifdef __EDG_VERSION__ #endif // __EDG_VERSION__ //////////////////////////////////////////////////////////////////////////////// // Digital Mars #ifdef __DMC__ #endif // __DMC__ //////////////////////////////////////////////////////////////////////////////// // GCC #ifdef __GNUC__ # if __GNUC__ == 4 && __GNUC_MINOR__ >= 6 && defined(__GXX_EXPERIMENTAL_CXX0X__) # define CATCH_INTERNAL_CONFIG_CPP11_NULLPTR # endif // - otherwise more recent versions define __cplusplus >= 201103L // and will get picked up below #endif // __GNUC__ //////////////////////////////////////////////////////////////////////////////// // Visual C++ #ifdef _MSC_VER #define CATCH_INTERNAL_CONFIG_WINDOWS_SEH #if (_MSC_VER >= 1600) # define CATCH_INTERNAL_CONFIG_CPP11_NULLPTR # define CATCH_INTERNAL_CONFIG_CPP11_UNIQUE_PTR #endif #if (_MSC_VER >= 1900 ) // (VC++ 13 (VS2015)) #define CATCH_INTERNAL_CONFIG_CPP11_NOEXCEPT #define CATCH_INTERNAL_CONFIG_CPP11_GENERATED_METHODS #define CATCH_INTERNAL_CONFIG_CPP11_SHUFFLE #define CATCH_INTERNAL_CONFIG_CPP11_TYPE_TRAITS #endif #endif // _MSC_VER //////////////////////////////////////////////////////////////////////////////// // Use variadic macros if the compiler supports them #if ( defined _MSC_VER && _MSC_VER > 1400 && !defined __EDGE__) || \ ( defined __WAVE__ && __WAVE_HAS_VARIADICS ) || \ ( defined __GNUC__ && __GNUC__ >= 3 ) || \ ( !defined __cplusplus && __STDC_VERSION__ >= 199901L || __cplusplus >= 201103L ) #define CATCH_INTERNAL_CONFIG_VARIADIC_MACROS #endif // Use __COUNTER__ if the compiler supports it #if ( defined _MSC_VER && _MSC_VER >= 1300 ) || \ ( defined __GNUC__ && ( __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3 )) ) || \ ( defined __clang__ && __clang_major__ >= 3 ) // Use of __COUNTER__ is suppressed during code analysis in CLion/AppCode 2017.2.x and former, // because __COUNTER__ is not properly handled by it. // This does not affect compilation #if ( !defined __JETBRAINS_IDE__ || __JETBRAINS_IDE__ >= 20170300L ) #define CATCH_INTERNAL_CONFIG_COUNTER #endif #endif //////////////////////////////////////////////////////////////////////////////// // C++ language feature support // catch all support for C++11 #if defined(CATCH_CPP11_OR_GREATER) # if !defined(CATCH_INTERNAL_CONFIG_CPP11_NULLPTR) # define CATCH_INTERNAL_CONFIG_CPP11_NULLPTR # endif # ifndef CATCH_INTERNAL_CONFIG_CPP11_NOEXCEPT # define CATCH_INTERNAL_CONFIG_CPP11_NOEXCEPT # endif # ifndef CATCH_INTERNAL_CONFIG_CPP11_GENERATED_METHODS # define CATCH_INTERNAL_CONFIG_CPP11_GENERATED_METHODS # endif # ifndef CATCH_INTERNAL_CONFIG_CPP11_IS_ENUM # define CATCH_INTERNAL_CONFIG_CPP11_IS_ENUM # endif # ifndef CATCH_INTERNAL_CONFIG_CPP11_TUPLE # define CATCH_INTERNAL_CONFIG_CPP11_TUPLE # endif # ifndef CATCH_INTERNAL_CONFIG_VARIADIC_MACROS # define CATCH_INTERNAL_CONFIG_VARIADIC_MACROS # endif # if !defined(CATCH_INTERNAL_CONFIG_CPP11_LONG_LONG) # define CATCH_INTERNAL_CONFIG_CPP11_LONG_LONG # endif # if !defined(CATCH_INTERNAL_CONFIG_CPP11_OVERRIDE) # define CATCH_INTERNAL_CONFIG_CPP11_OVERRIDE # endif # if !defined(CATCH_INTERNAL_CONFIG_CPP11_UNIQUE_PTR) # define CATCH_INTERNAL_CONFIG_CPP11_UNIQUE_PTR # endif # if !defined(CATCH_INTERNAL_CONFIG_CPP11_SHUFFLE) # define CATCH_INTERNAL_CONFIG_CPP11_SHUFFLE # endif # if !defined(CATCH_INTERNAL_CONFIG_CPP11_TYPE_TRAITS) # define CATCH_INTERNAL_CONFIG_CPP11_TYPE_TRAITS # endif #endif // __cplusplus >= 201103L // Now set the actual defines based on the above + anything the user has configured #if defined(CATCH_INTERNAL_CONFIG_CPP11_NULLPTR) && !defined(CATCH_CONFIG_CPP11_NO_NULLPTR) && !defined(CATCH_CONFIG_CPP11_NULLPTR) && !defined(CATCH_CONFIG_NO_CPP11) # define CATCH_CONFIG_CPP11_NULLPTR #endif #if defined(CATCH_INTERNAL_CONFIG_CPP11_NOEXCEPT) && !defined(CATCH_CONFIG_CPP11_NO_NOEXCEPT) && !defined(CATCH_CONFIG_CPP11_NOEXCEPT) && !defined(CATCH_CONFIG_NO_CPP11) # define CATCH_CONFIG_CPP11_NOEXCEPT #endif #if defined(CATCH_INTERNAL_CONFIG_CPP11_GENERATED_METHODS) && !defined(CATCH_CONFIG_CPP11_NO_GENERATED_METHODS) && !defined(CATCH_CONFIG_CPP11_GENERATED_METHODS) && !defined(CATCH_CONFIG_NO_CPP11) # define CATCH_CONFIG_CPP11_GENERATED_METHODS #endif #if defined(CATCH_INTERNAL_CONFIG_CPP11_IS_ENUM) && !defined(CATCH_CONFIG_CPP11_NO_IS_ENUM) && !defined(CATCH_CONFIG_CPP11_IS_ENUM) && !defined(CATCH_CONFIG_NO_CPP11) # define CATCH_CONFIG_CPP11_IS_ENUM #endif #if defined(CATCH_INTERNAL_CONFIG_CPP11_TUPLE) && !defined(CATCH_CONFIG_CPP11_NO_TUPLE) && !defined(CATCH_CONFIG_CPP11_TUPLE) && !defined(CATCH_CONFIG_NO_CPP11) # define CATCH_CONFIG_CPP11_TUPLE #endif #if defined(CATCH_INTERNAL_CONFIG_VARIADIC_MACROS) && !defined(CATCH_CONFIG_NO_VARIADIC_MACROS) && !defined(CATCH_CONFIG_VARIADIC_MACROS) # define CATCH_CONFIG_VARIADIC_MACROS #endif #if defined(CATCH_INTERNAL_CONFIG_CPP11_LONG_LONG) && !defined(CATCH_CONFIG_CPP11_NO_LONG_LONG) && !defined(CATCH_CONFIG_CPP11_LONG_LONG) && !defined(CATCH_CONFIG_NO_CPP11) # define CATCH_CONFIG_CPP11_LONG_LONG #endif #if defined(CATCH_INTERNAL_CONFIG_CPP11_OVERRIDE) && !defined(CATCH_CONFIG_CPP11_NO_OVERRIDE) && !defined(CATCH_CONFIG_CPP11_OVERRIDE) && !defined(CATCH_CONFIG_NO_CPP11) # define CATCH_CONFIG_CPP11_OVERRIDE #endif #if defined(CATCH_INTERNAL_CONFIG_CPP11_UNIQUE_PTR) && !defined(CATCH_CONFIG_CPP11_NO_UNIQUE_PTR) && !defined(CATCH_CONFIG_CPP11_UNIQUE_PTR) && !defined(CATCH_CONFIG_NO_CPP11) # define CATCH_CONFIG_CPP11_UNIQUE_PTR #endif #if defined(CATCH_INTERNAL_CONFIG_COUNTER) && !defined(CATCH_CONFIG_NO_COUNTER) && !defined(CATCH_CONFIG_COUNTER) # define CATCH_CONFIG_COUNTER #endif #if defined(CATCH_INTERNAL_CONFIG_CPP11_SHUFFLE) && !defined(CATCH_CONFIG_CPP11_NO_SHUFFLE) && !defined(CATCH_CONFIG_CPP11_SHUFFLE) && !defined(CATCH_CONFIG_NO_CPP11) # define CATCH_CONFIG_CPP11_SHUFFLE #endif # if defined(CATCH_INTERNAL_CONFIG_CPP11_TYPE_TRAITS) && !defined(CATCH_CONFIG_CPP11_NO_TYPE_TRAITS) && !defined(CATCH_CONFIG_CPP11_TYPE_TRAITS) && !defined(CATCH_CONFIG_NO_CPP11) # define CATCH_CONFIG_CPP11_TYPE_TRAITS # endif #if defined(CATCH_INTERNAL_CONFIG_WINDOWS_SEH) && !defined(CATCH_CONFIG_NO_WINDOWS_SEH) && !defined(CATCH_CONFIG_WINDOWS_SEH) # define CATCH_CONFIG_WINDOWS_SEH #endif // This is set by default, because we assume that unix compilers are posix-signal-compatible by default. #if !defined(CATCH_INTERNAL_CONFIG_NO_POSIX_SIGNALS) && !defined(CATCH_CONFIG_NO_POSIX_SIGNALS) && !defined(CATCH_CONFIG_POSIX_SIGNALS) # define CATCH_CONFIG_POSIX_SIGNALS #endif #if !defined(CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS) # define CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS # define CATCH_INTERNAL_UNSUPPRESS_PARENTHESES_WARNINGS #endif #if !defined(CATCH_INTERNAL_SUPPRESS_ETD_WARNINGS) # define CATCH_INTERNAL_SUPPRESS_ETD_WARNINGS # define CATCH_INTERNAL_UNSUPPRESS_ETD_WARNINGS #endif // noexcept support: #if defined(CATCH_CONFIG_CPP11_NOEXCEPT) && !defined(CATCH_NOEXCEPT) # define CATCH_NOEXCEPT noexcept # define CATCH_NOEXCEPT_IS(x) noexcept(x) #else # define CATCH_NOEXCEPT throw() # define CATCH_NOEXCEPT_IS(x) #endif // nullptr support #ifdef CATCH_CONFIG_CPP11_NULLPTR # define CATCH_NULL nullptr #else # define CATCH_NULL NULL #endif // override support #ifdef CATCH_CONFIG_CPP11_OVERRIDE # define CATCH_OVERRIDE override #else # define CATCH_OVERRIDE #endif // unique_ptr support #ifdef CATCH_CONFIG_CPP11_UNIQUE_PTR # define CATCH_AUTO_PTR( T ) std::unique_ptr #else # define CATCH_AUTO_PTR( T ) std::auto_ptr #endif #define INTERNAL_CATCH_UNIQUE_NAME_LINE2( name, line ) name##line #define INTERNAL_CATCH_UNIQUE_NAME_LINE( name, line ) INTERNAL_CATCH_UNIQUE_NAME_LINE2( name, line ) #ifdef CATCH_CONFIG_COUNTER # define INTERNAL_CATCH_UNIQUE_NAME( name ) INTERNAL_CATCH_UNIQUE_NAME_LINE( name, __COUNTER__ ) #else # define INTERNAL_CATCH_UNIQUE_NAME( name ) INTERNAL_CATCH_UNIQUE_NAME_LINE( name, __LINE__ ) #endif #define INTERNAL_CATCH_STRINGIFY2( expr ) #expr #define INTERNAL_CATCH_STRINGIFY( expr ) INTERNAL_CATCH_STRINGIFY2( expr ) #include #include namespace Catch { struct IConfig; struct CaseSensitive { enum Choice { Yes, No }; }; class NonCopyable { #ifdef CATCH_CONFIG_CPP11_GENERATED_METHODS NonCopyable( NonCopyable const& ) = delete; NonCopyable( NonCopyable && ) = delete; NonCopyable& operator = ( NonCopyable const& ) = delete; NonCopyable& operator = ( NonCopyable && ) = delete; #else NonCopyable( NonCopyable const& info ); NonCopyable& operator = ( NonCopyable const& ); #endif protected: NonCopyable() {} virtual ~NonCopyable(); }; class SafeBool { public: typedef void (SafeBool::*type)() const; static type makeSafe( bool value ) { return value ? &SafeBool::trueValue : 0; } private: void trueValue() const {} }; template void deleteAll( ContainerT& container ) { typename ContainerT::const_iterator it = container.begin(); typename ContainerT::const_iterator itEnd = container.end(); for(; it != itEnd; ++it ) delete *it; } template void deleteAllValues( AssociativeContainerT& container ) { typename AssociativeContainerT::const_iterator it = container.begin(); typename AssociativeContainerT::const_iterator itEnd = container.end(); for(; it != itEnd; ++it ) delete it->second; } bool startsWith( std::string const& s, std::string const& prefix ); bool startsWith( std::string const& s, char prefix ); bool endsWith( std::string const& s, std::string const& suffix ); bool endsWith( std::string const& s, char suffix ); bool contains( std::string const& s, std::string const& infix ); void toLowerInPlace( std::string& s ); std::string toLower( std::string const& s ); std::string trim( std::string const& str ); bool replaceInPlace( std::string& str, std::string const& replaceThis, std::string const& withThis ); struct pluralise { pluralise( std::size_t count, std::string const& label ); friend std::ostream& operator << ( std::ostream& os, pluralise const& pluraliser ); std::size_t m_count; std::string m_label; }; struct SourceLineInfo { SourceLineInfo(); SourceLineInfo( char const* _file, std::size_t _line ); # ifdef CATCH_CONFIG_CPP11_GENERATED_METHODS SourceLineInfo(SourceLineInfo const& other) = default; SourceLineInfo( SourceLineInfo && ) = default; SourceLineInfo& operator = ( SourceLineInfo const& ) = default; SourceLineInfo& operator = ( SourceLineInfo && ) = default; # endif bool empty() const; bool operator == ( SourceLineInfo const& other ) const; bool operator < ( SourceLineInfo const& other ) const; char const* file; std::size_t line; }; std::ostream& operator << ( std::ostream& os, SourceLineInfo const& info ); // This is just here to avoid compiler warnings with macro constants and boolean literals inline bool isTrue( bool value ){ return value; } inline bool alwaysTrue() { return true; } inline bool alwaysFalse() { return false; } void throwLogicError( std::string const& message, SourceLineInfo const& locationInfo ); void seedRng( IConfig const& config ); unsigned int rngSeed(); // Use this in variadic streaming macros to allow // >> +StreamEndStop // as well as // >> stuff +StreamEndStop struct StreamEndStop { std::string operator+() { return std::string(); } }; template T const& operator + ( T const& value, StreamEndStop ) { return value; } } #define CATCH_INTERNAL_LINEINFO ::Catch::SourceLineInfo( __FILE__, static_cast( __LINE__ ) ) #define CATCH_INTERNAL_ERROR( msg ) ::Catch::throwLogicError( msg, CATCH_INTERNAL_LINEINFO ); namespace Catch { class NotImplementedException : public std::exception { public: NotImplementedException( SourceLineInfo const& lineInfo ); virtual ~NotImplementedException() CATCH_NOEXCEPT {} virtual const char* what() const CATCH_NOEXCEPT; private: std::string m_what; SourceLineInfo m_lineInfo; }; } // end namespace Catch /////////////////////////////////////////////////////////////////////////////// #define CATCH_NOT_IMPLEMENTED throw Catch::NotImplementedException( CATCH_INTERNAL_LINEINFO ) // #included from: internal/catch_context.h #define TWOBLUECUBES_CATCH_CONTEXT_H_INCLUDED // #included from: catch_interfaces_generators.h #define TWOBLUECUBES_CATCH_INTERFACES_GENERATORS_H_INCLUDED #include namespace Catch { struct IGeneratorInfo { virtual ~IGeneratorInfo(); virtual bool moveNext() = 0; virtual std::size_t getCurrentIndex() const = 0; }; struct IGeneratorsForTest { virtual ~IGeneratorsForTest(); virtual IGeneratorInfo& getGeneratorInfo( std::string const& fileInfo, std::size_t size ) = 0; virtual bool moveNext() = 0; }; IGeneratorsForTest* createGeneratorsForTest(); } // end namespace Catch // #included from: catch_ptr.hpp #define TWOBLUECUBES_CATCH_PTR_HPP_INCLUDED #ifdef __clang__ #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wpadded" #endif namespace Catch { // An intrusive reference counting smart pointer. // T must implement addRef() and release() methods // typically implementing the IShared interface template class Ptr { public: Ptr() : m_p( CATCH_NULL ){} Ptr( T* p ) : m_p( p ){ if( m_p ) m_p->addRef(); } Ptr( Ptr const& other ) : m_p( other.m_p ){ if( m_p ) m_p->addRef(); } ~Ptr(){ if( m_p ) m_p->release(); } void reset() { if( m_p ) m_p->release(); m_p = CATCH_NULL; } Ptr& operator = ( T* p ){ Ptr temp( p ); swap( temp ); return *this; } Ptr& operator = ( Ptr const& other ){ Ptr temp( other ); swap( temp ); return *this; } void swap( Ptr& other ) { std::swap( m_p, other.m_p ); } T* get() const{ return m_p; } T& operator*() const { return *m_p; } T* operator->() const { return m_p; } bool operator !() const { return m_p == CATCH_NULL; } operator SafeBool::type() const { return SafeBool::makeSafe( m_p != CATCH_NULL ); } private: T* m_p; }; struct IShared : NonCopyable { virtual ~IShared(); virtual void addRef() const = 0; virtual void release() const = 0; }; template struct SharedImpl : T { SharedImpl() : m_rc( 0 ){} virtual void addRef() const { ++m_rc; } virtual void release() const { if( --m_rc == 0 ) delete this; } mutable unsigned int m_rc; }; } // end namespace Catch #ifdef __clang__ #pragma clang diagnostic pop #endif namespace Catch { class TestCase; class Stream; struct IResultCapture; struct IRunner; struct IGeneratorsForTest; struct IConfig; struct IContext { virtual ~IContext(); virtual IResultCapture* getResultCapture() = 0; virtual IRunner* getRunner() = 0; virtual size_t getGeneratorIndex( std::string const& fileInfo, size_t totalSize ) = 0; virtual bool advanceGeneratorsForCurrentTest() = 0; virtual Ptr getConfig() const = 0; }; struct IMutableContext : IContext { virtual ~IMutableContext(); virtual void setResultCapture( IResultCapture* resultCapture ) = 0; virtual void setRunner( IRunner* runner ) = 0; virtual void setConfig( Ptr const& config ) = 0; }; IContext& getCurrentContext(); IMutableContext& getCurrentMutableContext(); void cleanUpContext(); Stream createStream( std::string const& streamName ); } // #included from: internal/catch_test_registry.hpp #define TWOBLUECUBES_CATCH_TEST_REGISTRY_HPP_INCLUDED // #included from: catch_interfaces_testcase.h #define TWOBLUECUBES_CATCH_INTERFACES_TESTCASE_H_INCLUDED #include namespace Catch { class TestSpec; struct ITestCase : IShared { virtual void invoke () const = 0; protected: virtual ~ITestCase(); }; class TestCase; struct IConfig; struct ITestCaseRegistry { virtual ~ITestCaseRegistry(); virtual std::vector const& getAllTests() const = 0; virtual std::vector const& getAllTestsSorted( IConfig const& config ) const = 0; }; bool matchTest( TestCase const& testCase, TestSpec const& testSpec, IConfig const& config ); std::vector filterTests( std::vector const& testCases, TestSpec const& testSpec, IConfig const& config ); std::vector const& getAllTestCasesSorted( IConfig const& config ); } namespace Catch { template class MethodTestCase : public SharedImpl { public: MethodTestCase( void (C::*method)() ) : m_method( method ) {} virtual void invoke() const { C obj; (obj.*m_method)(); } private: virtual ~MethodTestCase() {} void (C::*m_method)(); }; typedef void(*TestFunction)(); struct NameAndDesc { NameAndDesc( const char* _name = "", const char* _description= "" ) : name( _name ), description( _description ) {} const char* name; const char* description; }; void registerTestCase ( ITestCase* testCase, char const* className, NameAndDesc const& nameAndDesc, SourceLineInfo const& lineInfo ); struct AutoReg { AutoReg ( TestFunction function, SourceLineInfo const& lineInfo, NameAndDesc const& nameAndDesc ); template AutoReg ( void (C::*method)(), char const* className, NameAndDesc const& nameAndDesc, SourceLineInfo const& lineInfo ) { registerTestCase ( new MethodTestCase( method ), className, nameAndDesc, lineInfo ); } ~AutoReg(); private: AutoReg( AutoReg const& ); void operator= ( AutoReg const& ); }; void registerTestCaseFunction ( TestFunction function, SourceLineInfo const& lineInfo, NameAndDesc const& nameAndDesc ); } // end namespace Catch #ifdef CATCH_CONFIG_VARIADIC_MACROS /////////////////////////////////////////////////////////////////////////////// #define INTERNAL_CATCH_TESTCASE2( TestName, ... ) \ static void TestName(); \ CATCH_INTERNAL_SUPPRESS_ETD_WARNINGS \ namespace{ Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( &TestName, CATCH_INTERNAL_LINEINFO, Catch::NameAndDesc( __VA_ARGS__ ) ); } /* NOLINT */ \ CATCH_INTERNAL_UNSUPPRESS_ETD_WARNINGS \ static void TestName() #define INTERNAL_CATCH_TESTCASE( ... ) \ INTERNAL_CATCH_TESTCASE2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ), __VA_ARGS__ ) /////////////////////////////////////////////////////////////////////////////// #define INTERNAL_CATCH_METHOD_AS_TEST_CASE( QualifiedMethod, ... ) \ CATCH_INTERNAL_SUPPRESS_ETD_WARNINGS \ namespace{ Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( &QualifiedMethod, "&" #QualifiedMethod, Catch::NameAndDesc( __VA_ARGS__ ), CATCH_INTERNAL_LINEINFO ); } /* NOLINT */ \ CATCH_INTERNAL_UNSUPPRESS_ETD_WARNINGS /////////////////////////////////////////////////////////////////////////////// #define INTERNAL_CATCH_TEST_CASE_METHOD2( TestName, ClassName, ... )\ CATCH_INTERNAL_SUPPRESS_ETD_WARNINGS \ namespace{ \ struct TestName : ClassName{ \ void test(); \ }; \ Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar ) ( &TestName::test, #ClassName, Catch::NameAndDesc( __VA_ARGS__ ), CATCH_INTERNAL_LINEINFO ); /* NOLINT */ \ } \ CATCH_INTERNAL_UNSUPPRESS_ETD_WARNINGS \ void TestName::test() #define INTERNAL_CATCH_TEST_CASE_METHOD( ClassName, ... ) \ INTERNAL_CATCH_TEST_CASE_METHOD2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ), ClassName, __VA_ARGS__ ) /////////////////////////////////////////////////////////////////////////////// #define INTERNAL_CATCH_REGISTER_TESTCASE( Function, ... ) \ CATCH_INTERNAL_SUPPRESS_ETD_WARNINGS \ Catch::AutoReg( Function, CATCH_INTERNAL_LINEINFO, Catch::NameAndDesc( __VA_ARGS__ ) ); /* NOLINT */ \ CATCH_INTERNAL_UNSUPPRESS_ETD_WARNINGS #else /////////////////////////////////////////////////////////////////////////////// #define INTERNAL_CATCH_TESTCASE2( TestName, Name, Desc ) \ static void TestName(); \ CATCH_INTERNAL_SUPPRESS_ETD_WARNINGS \ namespace{ Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( &TestName, CATCH_INTERNAL_LINEINFO, Catch::NameAndDesc( Name, Desc ) ); } /* NOLINT */ \ CATCH_INTERNAL_UNSUPPRESS_ETD_WARNINGS \ static void TestName() #define INTERNAL_CATCH_TESTCASE( Name, Desc ) \ INTERNAL_CATCH_TESTCASE2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ), Name, Desc ) /////////////////////////////////////////////////////////////////////////////// #define INTERNAL_CATCH_METHOD_AS_TEST_CASE( QualifiedMethod, Name, Desc ) \ CATCH_INTERNAL_SUPPRESS_ETD_WARNINGS \ namespace{ Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( &QualifiedMethod, "&" #QualifiedMethod, Catch::NameAndDesc( Name, Desc ), CATCH_INTERNAL_LINEINFO ); } /* NOLINT */ \ CATCH_INTERNAL_UNSUPPRESS_ETD_WARNINGS /////////////////////////////////////////////////////////////////////////////// #define INTERNAL_CATCH_TEST_CASE_METHOD2( TestCaseName, ClassName, TestName, Desc )\ CATCH_INTERNAL_SUPPRESS_ETD_WARNINGS \ namespace{ \ struct TestCaseName : ClassName{ \ void test(); \ }; \ Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar ) ( &TestCaseName::test, #ClassName, Catch::NameAndDesc( TestName, Desc ), CATCH_INTERNAL_LINEINFO ); /* NOLINT */ \ } \ CATCH_INTERNAL_UNSUPPRESS_ETD_WARNINGS \ void TestCaseName::test() #define INTERNAL_CATCH_TEST_CASE_METHOD( ClassName, TestName, Desc )\ INTERNAL_CATCH_TEST_CASE_METHOD2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ), ClassName, TestName, Desc ) /////////////////////////////////////////////////////////////////////////////// #define INTERNAL_CATCH_REGISTER_TESTCASE( Function, Name, Desc ) \ CATCH_INTERNAL_SUPPRESS_ETD_WARNINGS \ Catch::AutoReg( Function, CATCH_INTERNAL_LINEINFO, Catch::NameAndDesc( Name, Desc ) ); /* NOLINT */ \ CATCH_INTERNAL_UNSUPPRESS_ETD_WARNINGS #endif // #included from: internal/catch_capture.hpp #define TWOBLUECUBES_CATCH_CAPTURE_HPP_INCLUDED // #included from: catch_result_builder.h #define TWOBLUECUBES_CATCH_RESULT_BUILDER_H_INCLUDED // #included from: catch_result_type.h #define TWOBLUECUBES_CATCH_RESULT_TYPE_H_INCLUDED namespace Catch { // ResultWas::OfType enum struct ResultWas { enum OfType { Unknown = -1, Ok = 0, Info = 1, Warning = 2, FailureBit = 0x10, ExpressionFailed = FailureBit | 1, ExplicitFailure = FailureBit | 2, Exception = 0x100 | FailureBit, ThrewException = Exception | 1, DidntThrowException = Exception | 2, FatalErrorCondition = 0x200 | FailureBit }; }; inline bool isOk( ResultWas::OfType resultType ) { return ( resultType & ResultWas::FailureBit ) == 0; } inline bool isJustInfo( int flags ) { return flags == ResultWas::Info; } // ResultDisposition::Flags enum struct ResultDisposition { enum Flags { Normal = 0x01, ContinueOnFailure = 0x02, // Failures fail test, but execution continues FalseTest = 0x04, // Prefix expression with ! SuppressFail = 0x08 // Failures are reported but do not fail the test }; }; inline ResultDisposition::Flags operator | ( ResultDisposition::Flags lhs, ResultDisposition::Flags rhs ) { return static_cast( static_cast( lhs ) | static_cast( rhs ) ); } inline bool shouldContinueOnFailure( int flags ) { return ( flags & ResultDisposition::ContinueOnFailure ) != 0; } inline bool isFalseTest( int flags ) { return ( flags & ResultDisposition::FalseTest ) != 0; } inline bool shouldSuppressFailure( int flags ) { return ( flags & ResultDisposition::SuppressFail ) != 0; } } // end namespace Catch // #included from: catch_assertionresult.h #define TWOBLUECUBES_CATCH_ASSERTIONRESULT_H_INCLUDED #include namespace Catch { struct STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison; struct DecomposedExpression { virtual ~DecomposedExpression() {} virtual bool isBinaryExpression() const { return false; } virtual void reconstructExpression( std::string& dest ) const = 0; // Only simple binary comparisons can be decomposed. // If more complex check is required then wrap sub-expressions in parentheses. template STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator + ( T const& ); template STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator - ( T const& ); template STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator * ( T const& ); template STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator / ( T const& ); template STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator % ( T const& ); template STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator && ( T const& ); template STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator || ( T const& ); private: DecomposedExpression& operator = (DecomposedExpression const&); }; struct AssertionInfo { AssertionInfo(); AssertionInfo( char const * _macroName, SourceLineInfo const& _lineInfo, char const * _capturedExpression, ResultDisposition::Flags _resultDisposition, char const * _secondArg = ""); char const * macroName; SourceLineInfo lineInfo; char const * capturedExpression; ResultDisposition::Flags resultDisposition; char const * secondArg; }; struct AssertionResultData { AssertionResultData() : decomposedExpression( CATCH_NULL ) , resultType( ResultWas::Unknown ) , negated( false ) , parenthesized( false ) {} void negate( bool parenthesize ) { negated = !negated; parenthesized = parenthesize; if( resultType == ResultWas::Ok ) resultType = ResultWas::ExpressionFailed; else if( resultType == ResultWas::ExpressionFailed ) resultType = ResultWas::Ok; } std::string const& reconstructExpression() const { if( decomposedExpression != CATCH_NULL ) { decomposedExpression->reconstructExpression( reconstructedExpression ); if( parenthesized ) { reconstructedExpression.insert( 0, 1, '(' ); reconstructedExpression.append( 1, ')' ); } if( negated ) { reconstructedExpression.insert( 0, 1, '!' ); } decomposedExpression = CATCH_NULL; } return reconstructedExpression; } mutable DecomposedExpression const* decomposedExpression; mutable std::string reconstructedExpression; std::string message; ResultWas::OfType resultType; bool negated; bool parenthesized; }; class AssertionResult { public: AssertionResult(); AssertionResult( AssertionInfo const& info, AssertionResultData const& data ); ~AssertionResult(); # ifdef CATCH_CONFIG_CPP11_GENERATED_METHODS AssertionResult( AssertionResult const& ) = default; AssertionResult( AssertionResult && ) = default; AssertionResult& operator = ( AssertionResult const& ) = default; AssertionResult& operator = ( AssertionResult && ) = default; # endif bool isOk() const; bool succeeded() const; ResultWas::OfType getResultType() const; bool hasExpression() const; bool hasMessage() const; std::string getExpression() const; std::string getExpressionInMacro() const; bool hasExpandedExpression() const; std::string getExpandedExpression() const; std::string getMessage() const; SourceLineInfo getSourceInfo() const; std::string getTestMacroName() const; void discardDecomposedExpression() const; void expandDecomposedExpression() const; protected: AssertionInfo m_info; AssertionResultData m_resultData; }; } // end namespace Catch // #included from: catch_matchers.hpp #define TWOBLUECUBES_CATCH_MATCHERS_HPP_INCLUDED namespace Catch { namespace Matchers { namespace Impl { template struct MatchAllOf; template struct MatchAnyOf; template struct MatchNotOf; class MatcherUntypedBase { public: std::string toString() const { if( m_cachedToString.empty() ) m_cachedToString = describe(); return m_cachedToString; } protected: virtual ~MatcherUntypedBase(); virtual std::string describe() const = 0; mutable std::string m_cachedToString; private: MatcherUntypedBase& operator = ( MatcherUntypedBase const& ); }; template struct MatcherMethod { virtual bool match( ObjectT const& arg ) const = 0; }; template struct MatcherMethod { virtual bool match( PtrT* arg ) const = 0; }; template struct MatcherBase : MatcherUntypedBase, MatcherMethod { MatchAllOf operator && ( MatcherBase const& other ) const; MatchAnyOf operator || ( MatcherBase const& other ) const; MatchNotOf operator ! () const; }; template struct MatchAllOf : MatcherBase { virtual bool match( ArgT const& arg ) const CATCH_OVERRIDE { for( std::size_t i = 0; i < m_matchers.size(); ++i ) { if (!m_matchers[i]->match(arg)) return false; } return true; } virtual std::string describe() const CATCH_OVERRIDE { std::string description; description.reserve( 4 + m_matchers.size()*32 ); description += "( "; for( std::size_t i = 0; i < m_matchers.size(); ++i ) { if( i != 0 ) description += " and "; description += m_matchers[i]->toString(); } description += " )"; return description; } MatchAllOf& operator && ( MatcherBase const& other ) { m_matchers.push_back( &other ); return *this; } std::vector const*> m_matchers; }; template struct MatchAnyOf : MatcherBase { virtual bool match( ArgT const& arg ) const CATCH_OVERRIDE { for( std::size_t i = 0; i < m_matchers.size(); ++i ) { if (m_matchers[i]->match(arg)) return true; } return false; } virtual std::string describe() const CATCH_OVERRIDE { std::string description; description.reserve( 4 + m_matchers.size()*32 ); description += "( "; for( std::size_t i = 0; i < m_matchers.size(); ++i ) { if( i != 0 ) description += " or "; description += m_matchers[i]->toString(); } description += " )"; return description; } MatchAnyOf& operator || ( MatcherBase const& other ) { m_matchers.push_back( &other ); return *this; } std::vector const*> m_matchers; }; template struct MatchNotOf : MatcherBase { MatchNotOf( MatcherBase const& underlyingMatcher ) : m_underlyingMatcher( underlyingMatcher ) {} virtual bool match( ArgT const& arg ) const CATCH_OVERRIDE { return !m_underlyingMatcher.match( arg ); } virtual std::string describe() const CATCH_OVERRIDE { return "not " + m_underlyingMatcher.toString(); } MatcherBase const& m_underlyingMatcher; }; template MatchAllOf MatcherBase::operator && ( MatcherBase const& other ) const { return MatchAllOf() && *this && other; } template MatchAnyOf MatcherBase::operator || ( MatcherBase const& other ) const { return MatchAnyOf() || *this || other; } template MatchNotOf MatcherBase::operator ! () const { return MatchNotOf( *this ); } } // namespace Impl // The following functions create the actual matcher objects. // This allows the types to be inferred // - deprecated: prefer ||, && and ! template Impl::MatchNotOf Not( Impl::MatcherBase const& underlyingMatcher ) { return Impl::MatchNotOf( underlyingMatcher ); } template Impl::MatchAllOf AllOf( Impl::MatcherBase const& m1, Impl::MatcherBase const& m2 ) { return Impl::MatchAllOf() && m1 && m2; } template Impl::MatchAllOf AllOf( Impl::MatcherBase const& m1, Impl::MatcherBase const& m2, Impl::MatcherBase const& m3 ) { return Impl::MatchAllOf() && m1 && m2 && m3; } template Impl::MatchAnyOf AnyOf( Impl::MatcherBase const& m1, Impl::MatcherBase const& m2 ) { return Impl::MatchAnyOf() || m1 || m2; } template Impl::MatchAnyOf AnyOf( Impl::MatcherBase const& m1, Impl::MatcherBase const& m2, Impl::MatcherBase const& m3 ) { return Impl::MatchAnyOf() || m1 || m2 || m3; } } // namespace Matchers using namespace Matchers; using Matchers::Impl::MatcherBase; } // namespace Catch namespace Catch { struct TestFailureException{}; template class ExpressionLhs; struct CopyableStream { CopyableStream() {} CopyableStream( CopyableStream const& other ) { oss << other.oss.str(); } CopyableStream& operator=( CopyableStream const& other ) { oss.str(std::string()); oss << other.oss.str(); return *this; } std::ostringstream oss; }; class ResultBuilder : public DecomposedExpression { public: ResultBuilder( char const* macroName, SourceLineInfo const& lineInfo, char const* capturedExpression, ResultDisposition::Flags resultDisposition, char const* secondArg = "" ); ~ResultBuilder(); template ExpressionLhs operator <= ( T const& operand ); ExpressionLhs operator <= ( bool value ); template ResultBuilder& operator << ( T const& value ) { stream().oss << value; return *this; } ResultBuilder& setResultType( ResultWas::OfType result ); ResultBuilder& setResultType( bool result ); void endExpression( DecomposedExpression const& expr ); virtual void reconstructExpression( std::string& dest ) const CATCH_OVERRIDE; AssertionResult build() const; AssertionResult build( DecomposedExpression const& expr ) const; void useActiveException( ResultDisposition::Flags resultDisposition = ResultDisposition::Normal ); void captureResult( ResultWas::OfType resultType ); void captureExpression(); void captureExpectedException( std::string const& expectedMessage ); void captureExpectedException( Matchers::Impl::MatcherBase const& matcher ); void handleResult( AssertionResult const& result ); void react(); bool shouldDebugBreak() const; bool allowThrows() const; template void captureMatch( ArgT const& arg, MatcherT const& matcher, char const* matcherString ); void setExceptionGuard(); void unsetExceptionGuard(); private: AssertionInfo m_assertionInfo; AssertionResultData m_data; CopyableStream &stream() { if(!m_usedStream) { m_usedStream = true; m_stream().oss.str(""); } return m_stream(); } static CopyableStream &m_stream() { static CopyableStream s; return s; } bool m_shouldDebugBreak; bool m_shouldThrow; bool m_guardException; bool m_usedStream; }; } // namespace Catch // Include after due to circular dependency: // #included from: catch_expression_lhs.hpp #define TWOBLUECUBES_CATCH_EXPRESSION_LHS_HPP_INCLUDED // #included from: catch_evaluate.hpp #define TWOBLUECUBES_CATCH_EVALUATE_HPP_INCLUDED #ifdef _MSC_VER #pragma warning(push) #pragma warning(disable:4389) // '==' : signed/unsigned mismatch #pragma warning(disable:4018) // more "signed/unsigned mismatch" #pragma warning(disable:4312) // Converting int to T* using reinterpret_cast (issue on x64 platform) #endif #include namespace Catch { namespace Internal { enum Operator { IsEqualTo, IsNotEqualTo, IsLessThan, IsGreaterThan, IsLessThanOrEqualTo, IsGreaterThanOrEqualTo }; template struct OperatorTraits { static const char* getName(){ return "*error*"; } }; template<> struct OperatorTraits { static const char* getName(){ return "=="; } }; template<> struct OperatorTraits { static const char* getName(){ return "!="; } }; template<> struct OperatorTraits { static const char* getName(){ return "<"; } }; template<> struct OperatorTraits { static const char* getName(){ return ">"; } }; template<> struct OperatorTraits { static const char* getName(){ return "<="; } }; template<> struct OperatorTraits{ static const char* getName(){ return ">="; } }; template T& opCast(T const& t) { return const_cast(t); } // nullptr_t support based on pull request #154 from Konstantin Baumann #ifdef CATCH_CONFIG_CPP11_NULLPTR inline std::nullptr_t opCast(std::nullptr_t) { return nullptr; } #endif // CATCH_CONFIG_CPP11_NULLPTR // So the compare overloads can be operator agnostic we convey the operator as a template // enum, which is used to specialise an Evaluator for doing the comparison. template struct Evaluator{}; template struct Evaluator { static bool evaluate( T1 const& lhs, T2 const& rhs) { return bool( opCast( lhs ) == opCast( rhs ) ); } }; template struct Evaluator { static bool evaluate( T1 const& lhs, T2 const& rhs ) { return bool( opCast( lhs ) != opCast( rhs ) ); } }; template struct Evaluator { static bool evaluate( T1 const& lhs, T2 const& rhs ) { return bool( opCast( lhs ) < opCast( rhs ) ); } }; template struct Evaluator { static bool evaluate( T1 const& lhs, T2 const& rhs ) { return bool( opCast( lhs ) > opCast( rhs ) ); } }; template struct Evaluator { static bool evaluate( T1 const& lhs, T2 const& rhs ) { return bool( opCast( lhs ) >= opCast( rhs ) ); } }; template struct Evaluator { static bool evaluate( T1 const& lhs, T2 const& rhs ) { return bool( opCast( lhs ) <= opCast( rhs ) ); } }; template bool applyEvaluator( T1 const& lhs, T2 const& rhs ) { return Evaluator::evaluate( lhs, rhs ); } // This level of indirection allows us to specialise for integer types // to avoid signed/ unsigned warnings // "base" overload template bool compare( T1 const& lhs, T2 const& rhs ) { return Evaluator::evaluate( lhs, rhs ); } // unsigned X to int template bool compare( unsigned int lhs, int rhs ) { return applyEvaluator( lhs, static_cast( rhs ) ); } template bool compare( unsigned long lhs, int rhs ) { return applyEvaluator( lhs, static_cast( rhs ) ); } template bool compare( unsigned char lhs, int rhs ) { return applyEvaluator( lhs, static_cast( rhs ) ); } // unsigned X to long template bool compare( unsigned int lhs, long rhs ) { return applyEvaluator( lhs, static_cast( rhs ) ); } template bool compare( unsigned long lhs, long rhs ) { return applyEvaluator( lhs, static_cast( rhs ) ); } template bool compare( unsigned char lhs, long rhs ) { return applyEvaluator( lhs, static_cast( rhs ) ); } // int to unsigned X template bool compare( int lhs, unsigned int rhs ) { return applyEvaluator( static_cast( lhs ), rhs ); } template bool compare( int lhs, unsigned long rhs ) { return applyEvaluator( static_cast( lhs ), rhs ); } template bool compare( int lhs, unsigned char rhs ) { return applyEvaluator( static_cast( lhs ), rhs ); } // long to unsigned X template bool compare( long lhs, unsigned int rhs ) { return applyEvaluator( static_cast( lhs ), rhs ); } template bool compare( long lhs, unsigned long rhs ) { return applyEvaluator( static_cast( lhs ), rhs ); } template bool compare( long lhs, unsigned char rhs ) { return applyEvaluator( static_cast( lhs ), rhs ); } // pointer to long (when comparing against NULL) template bool compare( long lhs, T* rhs ) { return Evaluator::evaluate( reinterpret_cast( lhs ), rhs ); } template bool compare( T* lhs, long rhs ) { return Evaluator::evaluate( lhs, reinterpret_cast( rhs ) ); } // pointer to int (when comparing against NULL) template bool compare( int lhs, T* rhs ) { return Evaluator::evaluate( reinterpret_cast( lhs ), rhs ); } template bool compare( T* lhs, int rhs ) { return Evaluator::evaluate( lhs, reinterpret_cast( rhs ) ); } #ifdef CATCH_CONFIG_CPP11_LONG_LONG // long long to unsigned X template bool compare( long long lhs, unsigned int rhs ) { return applyEvaluator( static_cast( lhs ), rhs ); } template bool compare( long long lhs, unsigned long rhs ) { return applyEvaluator( static_cast( lhs ), rhs ); } template bool compare( long long lhs, unsigned long long rhs ) { return applyEvaluator( static_cast( lhs ), rhs ); } template bool compare( long long lhs, unsigned char rhs ) { return applyEvaluator( static_cast( lhs ), rhs ); } // unsigned long long to X template bool compare( unsigned long long lhs, int rhs ) { return applyEvaluator( static_cast( lhs ), rhs ); } template bool compare( unsigned long long lhs, long rhs ) { return applyEvaluator( static_cast( lhs ), rhs ); } template bool compare( unsigned long long lhs, long long rhs ) { return applyEvaluator( static_cast( lhs ), rhs ); } template bool compare( unsigned long long lhs, char rhs ) { return applyEvaluator( static_cast( lhs ), rhs ); } // pointer to long long (when comparing against NULL) template bool compare( long long lhs, T* rhs ) { return Evaluator::evaluate( reinterpret_cast( lhs ), rhs ); } template bool compare( T* lhs, long long rhs ) { return Evaluator::evaluate( lhs, reinterpret_cast( rhs ) ); } #endif // CATCH_CONFIG_CPP11_LONG_LONG #ifdef CATCH_CONFIG_CPP11_NULLPTR // pointer to nullptr_t (when comparing against nullptr) template bool compare( std::nullptr_t, T* rhs ) { return Evaluator::evaluate( nullptr, rhs ); } template bool compare( T* lhs, std::nullptr_t ) { return Evaluator::evaluate( lhs, nullptr ); } #endif // CATCH_CONFIG_CPP11_NULLPTR } // end of namespace Internal } // end of namespace Catch #ifdef _MSC_VER #pragma warning(pop) #endif // #included from: catch_tostring.h #define TWOBLUECUBES_CATCH_TOSTRING_H_INCLUDED #include #include #include #include #include #ifdef __OBJC__ // #included from: catch_objc_arc.hpp #define TWOBLUECUBES_CATCH_OBJC_ARC_HPP_INCLUDED #import #ifdef __has_feature #define CATCH_ARC_ENABLED __has_feature(objc_arc) #else #define CATCH_ARC_ENABLED 0 #endif void arcSafeRelease( NSObject* obj ); id performOptionalSelector( id obj, SEL sel ); #if !CATCH_ARC_ENABLED inline void arcSafeRelease( NSObject* obj ) { [obj release]; } inline id performOptionalSelector( id obj, SEL sel ) { if( [obj respondsToSelector: sel] ) return [obj performSelector: sel]; return nil; } #define CATCH_UNSAFE_UNRETAINED #define CATCH_ARC_STRONG #else inline void arcSafeRelease( NSObject* ){} inline id performOptionalSelector( id obj, SEL sel ) { #ifdef __clang__ #pragma clang diagnostic push #pragma clang diagnostic ignored "-Warc-performSelector-leaks" #endif if( [obj respondsToSelector: sel] ) return [obj performSelector: sel]; #ifdef __clang__ #pragma clang diagnostic pop #endif return nil; } #define CATCH_UNSAFE_UNRETAINED __unsafe_unretained #define CATCH_ARC_STRONG __strong #endif #endif #ifdef CATCH_CONFIG_CPP11_TUPLE #include #endif #ifdef CATCH_CONFIG_CPP11_IS_ENUM #include #endif namespace Catch { // Why we're here. template std::string toString( T const& value ); // Built in overloads std::string toString( std::string const& value ); std::string toString( std::wstring const& value ); std::string toString( const char* const value ); std::string toString( char* const value ); std::string toString( const wchar_t* const value ); std::string toString( wchar_t* const value ); std::string toString( int value ); std::string toString( unsigned long value ); std::string toString( unsigned int value ); std::string toString( const double value ); std::string toString( const float value ); std::string toString( bool value ); std::string toString( char value ); std::string toString( signed char value ); std::string toString( unsigned char value ); #ifdef CATCH_CONFIG_CPP11_LONG_LONG std::string toString( long long value ); std::string toString( unsigned long long value ); #endif #ifdef CATCH_CONFIG_CPP11_NULLPTR std::string toString( std::nullptr_t ); #endif #ifdef __OBJC__ std::string toString( NSString const * const& nsstring ); std::string toString( NSString * CATCH_ARC_STRONG & nsstring ); std::string toString( NSObject* const& nsObject ); #endif namespace Detail { extern const std::string unprintableString; #if !defined(CATCH_CONFIG_CPP11_STREAM_INSERTABLE_CHECK) struct BorgType { template BorgType( T const& ); }; struct TrueType { char sizer[1]; }; struct FalseType { char sizer[2]; }; TrueType& testStreamable( std::ostream& ); FalseType testStreamable( FalseType ); FalseType operator<<( std::ostream const&, BorgType const& ); template struct IsStreamInsertable { static std::ostream &s; static T const&t; enum { value = sizeof( testStreamable(s << t) ) == sizeof( TrueType ) }; }; #else template class IsStreamInsertable { template static auto test(int) -> decltype( std::declval() << std::declval(), std::true_type() ); template static auto test(...) -> std::false_type; public: static const bool value = decltype(test(0))::value; }; #endif #if defined(CATCH_CONFIG_CPP11_IS_ENUM) template::value > struct EnumStringMaker { static std::string convert( T const& ) { return unprintableString; } }; template struct EnumStringMaker { static std::string convert( T const& v ) { return ::Catch::toString( static_cast::type>(v) ); } }; #endif template struct StringMakerBase { #if defined(CATCH_CONFIG_CPP11_IS_ENUM) template static std::string convert( T const& v ) { return EnumStringMaker::convert( v ); } #else template static std::string convert( T const& ) { return unprintableString; } #endif }; template<> struct StringMakerBase { template static std::string convert( T const& _value ) { std::ostringstream oss; oss << _value; return oss.str(); } }; std::string rawMemoryToString( const void *object, std::size_t size ); template std::string rawMemoryToString( const T& object ) { return rawMemoryToString( &object, sizeof(object) ); } } // end namespace Detail template struct StringMaker : Detail::StringMakerBase::value> {}; template struct StringMaker { template static std::string convert( U* p ) { if( !p ) return "NULL"; else return Detail::rawMemoryToString( p ); } }; template struct StringMaker { static std::string convert( R C::* p ) { if( !p ) return "NULL"; else return Detail::rawMemoryToString( p ); } }; namespace Detail { template std::string rangeToString( InputIterator first, InputIterator last ); } //template //struct StringMaker > { // static std::string convert( std::vector const& v ) { // return Detail::rangeToString( v.begin(), v.end() ); // } //}; template std::string toString( std::vector const& v ) { return Detail::rangeToString( v.begin(), v.end() ); } #ifdef CATCH_CONFIG_CPP11_TUPLE // toString for tuples namespace TupleDetail { template< typename Tuple, std::size_t N = 0, bool = (N < std::tuple_size::value) > struct ElementPrinter { static void print( const Tuple& tuple, std::ostream& os ) { os << ( N ? ", " : " " ) << Catch::toString(std::get(tuple)); ElementPrinter::print(tuple,os); } }; template< typename Tuple, std::size_t N > struct ElementPrinter { static void print( const Tuple&, std::ostream& ) {} }; } template struct StringMaker> { static std::string convert( const std::tuple& tuple ) { std::ostringstream os; os << '{'; TupleDetail::ElementPrinter>::print( tuple, os ); os << " }"; return os.str(); } }; #endif // CATCH_CONFIG_CPP11_TUPLE namespace Detail { template std::string makeString( T const& value ) { return StringMaker::convert( value ); } } // end namespace Detail /// \brief converts any type to a string /// /// The default template forwards on to ostringstream - except when an /// ostringstream overload does not exist - in which case it attempts to detect /// that and writes {?}. /// Overload (not specialise) this template for custom typs that you don't want /// to provide an ostream overload for. template std::string toString( T const& value ) { return StringMaker::convert( value ); } namespace Detail { template std::string rangeToString( InputIterator first, InputIterator last ) { std::ostringstream oss; oss << "{ "; if( first != last ) { oss << Catch::toString( *first ); for( ++first ; first != last ; ++first ) oss << ", " << Catch::toString( *first ); } oss << " }"; return oss.str(); } } } // end namespace Catch namespace Catch { template class BinaryExpression; template class MatchExpression; // Wraps the LHS of an expression and overloads comparison operators // for also capturing those and RHS (if any) template class ExpressionLhs : public DecomposedExpression { public: ExpressionLhs( ResultBuilder& rb, T lhs ) : m_rb( rb ), m_lhs( lhs ), m_truthy(false) {} ExpressionLhs& operator = ( const ExpressionLhs& ); template BinaryExpression operator == ( RhsT const& rhs ) { return captureExpression( rhs ); } template BinaryExpression operator != ( RhsT const& rhs ) { return captureExpression( rhs ); } template BinaryExpression operator < ( RhsT const& rhs ) { return captureExpression( rhs ); } template BinaryExpression operator > ( RhsT const& rhs ) { return captureExpression( rhs ); } template BinaryExpression operator <= ( RhsT const& rhs ) { return captureExpression( rhs ); } template BinaryExpression operator >= ( RhsT const& rhs ) { return captureExpression( rhs ); } BinaryExpression operator == ( bool rhs ) { return captureExpression( rhs ); } BinaryExpression operator != ( bool rhs ) { return captureExpression( rhs ); } void endExpression() { m_truthy = m_lhs ? true : false; m_rb .setResultType( m_truthy ) .endExpression( *this ); } virtual void reconstructExpression( std::string& dest ) const CATCH_OVERRIDE { dest = Catch::toString( m_lhs ); } private: template BinaryExpression captureExpression( RhsT& rhs ) const { return BinaryExpression( m_rb, m_lhs, rhs ); } template BinaryExpression captureExpression( bool rhs ) const { return BinaryExpression( m_rb, m_lhs, rhs ); } private: ResultBuilder& m_rb; T m_lhs; bool m_truthy; }; template class BinaryExpression : public DecomposedExpression { public: BinaryExpression( ResultBuilder& rb, LhsT lhs, RhsT rhs ) : m_rb( rb ), m_lhs( lhs ), m_rhs( rhs ) {} BinaryExpression& operator = ( BinaryExpression& ); void endExpression() const { m_rb .setResultType( Internal::compare( m_lhs, m_rhs ) ) .endExpression( *this ); } virtual bool isBinaryExpression() const CATCH_OVERRIDE { return true; } virtual void reconstructExpression( std::string& dest ) const CATCH_OVERRIDE { std::string lhs = Catch::toString( m_lhs ); std::string rhs = Catch::toString( m_rhs ); char delim = lhs.size() + rhs.size() < 40 && lhs.find('\n') == std::string::npos && rhs.find('\n') == std::string::npos ? ' ' : '\n'; dest.reserve( 7 + lhs.size() + rhs.size() ); // 2 for spaces around operator // 2 for operator // 2 for parentheses (conditionally added later) // 1 for negation (conditionally added later) dest = lhs; dest += delim; dest += Internal::OperatorTraits::getName(); dest += delim; dest += rhs; } private: ResultBuilder& m_rb; LhsT m_lhs; RhsT m_rhs; }; template class MatchExpression : public DecomposedExpression { public: MatchExpression( ArgT arg, MatcherT matcher, char const* matcherString ) : m_arg( arg ), m_matcher( matcher ), m_matcherString( matcherString ) {} virtual bool isBinaryExpression() const CATCH_OVERRIDE { return true; } virtual void reconstructExpression( std::string& dest ) const CATCH_OVERRIDE { std::string matcherAsString = m_matcher.toString(); dest = Catch::toString( m_arg ); dest += ' '; if( matcherAsString == Detail::unprintableString ) dest += m_matcherString; else dest += matcherAsString; } private: ArgT m_arg; MatcherT m_matcher; char const* m_matcherString; }; } // end namespace Catch namespace Catch { template ExpressionLhs ResultBuilder::operator <= ( T const& operand ) { return ExpressionLhs( *this, operand ); } inline ExpressionLhs ResultBuilder::operator <= ( bool value ) { return ExpressionLhs( *this, value ); } template void ResultBuilder::captureMatch( ArgT const& arg, MatcherT const& matcher, char const* matcherString ) { MatchExpression expr( arg, matcher, matcherString ); setResultType( matcher.match( arg ) ); endExpression( expr ); } } // namespace Catch // #included from: catch_message.h #define TWOBLUECUBES_CATCH_MESSAGE_H_INCLUDED #include namespace Catch { struct MessageInfo { MessageInfo( std::string const& _macroName, SourceLineInfo const& _lineInfo, ResultWas::OfType _type ); std::string macroName; SourceLineInfo lineInfo; ResultWas::OfType type; std::string message; unsigned int sequence; bool operator == ( MessageInfo const& other ) const { return sequence == other.sequence; } bool operator < ( MessageInfo const& other ) const { return sequence < other.sequence; } private: static unsigned int globalCount; }; struct MessageBuilder { MessageBuilder( std::string const& macroName, SourceLineInfo const& lineInfo, ResultWas::OfType type ) : m_info( macroName, lineInfo, type ) {} template MessageBuilder& operator << ( T const& value ) { m_stream << value; return *this; } MessageInfo m_info; std::ostringstream m_stream; }; class ScopedMessage { public: ScopedMessage( MessageBuilder const& builder ); ScopedMessage( ScopedMessage const& other ); ~ScopedMessage(); MessageInfo m_info; }; } // end namespace Catch // #included from: catch_interfaces_capture.h #define TWOBLUECUBES_CATCH_INTERFACES_CAPTURE_H_INCLUDED #include namespace Catch { class TestCase; class AssertionResult; struct AssertionInfo; struct SectionInfo; struct SectionEndInfo; struct MessageInfo; class ScopedMessageBuilder; struct Counts; struct IResultCapture { virtual ~IResultCapture(); virtual void assertionEnded( AssertionResult const& result ) = 0; virtual bool sectionStarted( SectionInfo const& sectionInfo, Counts& assertions ) = 0; virtual void sectionEnded( SectionEndInfo const& endInfo ) = 0; virtual void sectionEndedEarly( SectionEndInfo const& endInfo ) = 0; virtual void pushScopedMessage( MessageInfo const& message ) = 0; virtual void popScopedMessage( MessageInfo const& message ) = 0; virtual std::string getCurrentTestName() const = 0; virtual const AssertionResult* getLastResult() const = 0; virtual void exceptionEarlyReported() = 0; virtual void handleFatalErrorCondition( std::string const& message ) = 0; virtual bool lastAssertionPassed() = 0; virtual void assertionPassed() = 0; virtual void assertionRun() = 0; }; IResultCapture& getResultCapture(); } // #included from: catch_debugger.h #define TWOBLUECUBES_CATCH_DEBUGGER_H_INCLUDED // #included from: catch_platform.h #define TWOBLUECUBES_CATCH_PLATFORM_H_INCLUDED #if defined(__MAC_OS_X_VERSION_MIN_REQUIRED) # define CATCH_PLATFORM_MAC #elif defined(__IPHONE_OS_VERSION_MIN_REQUIRED) # define CATCH_PLATFORM_IPHONE #elif defined(linux) || defined(__linux) || defined(__linux__) # define CATCH_PLATFORM_LINUX #elif defined(WIN32) || defined(__WIN32__) || defined(_WIN32) || defined(_MSC_VER) # define CATCH_PLATFORM_WINDOWS # if !defined(NOMINMAX) && !defined(CATCH_CONFIG_NO_NOMINMAX) # define CATCH_DEFINES_NOMINMAX # endif # if !defined(WIN32_LEAN_AND_MEAN) && !defined(CATCH_CONFIG_NO_WIN32_LEAN_AND_MEAN) # define CATCH_DEFINES_WIN32_LEAN_AND_MEAN # endif #endif #include namespace Catch{ bool isDebuggerActive(); void writeToDebugConsole( std::string const& text ); } #ifdef CATCH_PLATFORM_MAC // The following code snippet based on: // http://cocoawithlove.com/2008/03/break-into-debugger.html #if defined(__ppc64__) || defined(__ppc__) #define CATCH_TRAP() \ __asm__("li r0, 20\nsc\nnop\nli r0, 37\nli r4, 2\nsc\nnop\n" \ : : : "memory","r0","r3","r4" ) /* NOLINT */ #else #define CATCH_TRAP() __asm__("int $3\n" : : /* NOLINT */ ) #endif #elif defined(CATCH_PLATFORM_LINUX) // If we can use inline assembler, do it because this allows us to break // directly at the location of the failing check instead of breaking inside // raise() called from it, i.e. one stack frame below. #if defined(__GNUC__) && (defined(__i386) || defined(__x86_64)) #define CATCH_TRAP() asm volatile ("int $3") /* NOLINT */ #else // Fall back to the generic way. #include #define CATCH_TRAP() raise(SIGTRAP) #endif #elif defined(_MSC_VER) #define CATCH_TRAP() __debugbreak() #elif defined(__MINGW32__) extern "C" __declspec(dllimport) void __stdcall DebugBreak(); #define CATCH_TRAP() DebugBreak() #endif #ifdef CATCH_TRAP #define CATCH_BREAK_INTO_DEBUGGER() if( Catch::isDebuggerActive() ) { CATCH_TRAP(); } #else #define CATCH_BREAK_INTO_DEBUGGER() Catch::alwaysTrue(); #endif // #included from: catch_interfaces_runner.h #define TWOBLUECUBES_CATCH_INTERFACES_RUNNER_H_INCLUDED namespace Catch { class TestCase; struct IRunner { virtual ~IRunner(); virtual bool aborting() const = 0; }; } #if !defined(CATCH_CONFIG_DISABLE_STRINGIFICATION) # define CATCH_INTERNAL_STRINGIFY(expr) #expr #else # define CATCH_INTERNAL_STRINGIFY(expr) "Disabled by CATCH_CONFIG_DISABLE_STRINGIFICATION" #endif #if defined(CATCH_CONFIG_FAST_COMPILE) /////////////////////////////////////////////////////////////////////////////// // We can speedup compilation significantly by breaking into debugger lower in // the callstack, because then we don't have to expand CATCH_BREAK_INTO_DEBUGGER // macro in each assertion #define INTERNAL_CATCH_REACT( resultBuilder ) \ resultBuilder.react(); /////////////////////////////////////////////////////////////////////////////// // Another way to speed-up compilation is to omit local try-catch for REQUIRE* // macros. // This can potentially cause false negative, if the test code catches // the exception before it propagates back up to the runner. #define INTERNAL_CATCH_TEST_NO_TRY( macroName, resultDisposition, expr ) \ do { \ Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(expr), resultDisposition ); \ __catchResult.setExceptionGuard(); \ CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS \ ( __catchResult <= expr ).endExpression(); \ CATCH_INTERNAL_UNSUPPRESS_PARENTHESES_WARNINGS \ __catchResult.unsetExceptionGuard(); \ INTERNAL_CATCH_REACT( __catchResult ) \ } while( Catch::isTrue( false && static_cast( !!(expr) ) ) ) // expr here is never evaluated at runtime but it forces the compiler to give it a look // The double negation silences MSVC's C4800 warning, the static_cast forces short-circuit evaluation if the type has overloaded &&. #define INTERNAL_CHECK_THAT_NO_TRY( macroName, matcher, resultDisposition, arg ) \ do { \ Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(arg) ", " CATCH_INTERNAL_STRINGIFY(matcher), resultDisposition ); \ __catchResult.setExceptionGuard(); \ __catchResult.captureMatch( arg, matcher, CATCH_INTERNAL_STRINGIFY(matcher) ); \ __catchResult.unsetExceptionGuard(); \ INTERNAL_CATCH_REACT( __catchResult ) \ } while( Catch::alwaysFalse() ) #else /////////////////////////////////////////////////////////////////////////////// // In the event of a failure works out if the debugger needs to be invoked // and/or an exception thrown and takes appropriate action. // This needs to be done as a macro so the debugger will stop in the user // source code rather than in Catch library code #define INTERNAL_CATCH_REACT( resultBuilder ) \ if( resultBuilder.shouldDebugBreak() ) CATCH_BREAK_INTO_DEBUGGER(); \ resultBuilder.react(); #endif /////////////////////////////////////////////////////////////////////////////// #define INTERNAL_CATCH_TEST( macroName, resultDisposition, expr ) \ do { \ Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(expr), resultDisposition ); \ try { \ CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS \ ( __catchResult <= expr ).endExpression(); \ CATCH_INTERNAL_UNSUPPRESS_PARENTHESES_WARNINGS \ } \ catch( ... ) { \ __catchResult.useActiveException( resultDisposition ); \ } \ INTERNAL_CATCH_REACT( __catchResult ) \ } while( Catch::isTrue( false && static_cast( !!(expr) ) ) ) // expr here is never evaluated at runtime but it forces the compiler to give it a look // The double negation silences MSVC's C4800 warning, the static_cast forces short-circuit evaluation if the type has overloaded &&. /////////////////////////////////////////////////////////////////////////////// #define INTERNAL_CATCH_IF( macroName, resultDisposition, expr ) \ INTERNAL_CATCH_TEST( macroName, resultDisposition, expr ); \ if( Catch::getResultCapture().lastAssertionPassed() ) /////////////////////////////////////////////////////////////////////////////// #define INTERNAL_CATCH_ELSE( macroName, resultDisposition, expr ) \ INTERNAL_CATCH_TEST( macroName, resultDisposition, expr ); \ if( !Catch::getResultCapture().lastAssertionPassed() ) /////////////////////////////////////////////////////////////////////////////// #define INTERNAL_CATCH_NO_THROW( macroName, resultDisposition, expr ) \ do { \ Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(expr), resultDisposition ); \ try { \ static_cast(expr); \ __catchResult.captureResult( Catch::ResultWas::Ok ); \ } \ catch( ... ) { \ __catchResult.useActiveException( resultDisposition ); \ } \ INTERNAL_CATCH_REACT( __catchResult ) \ } while( Catch::alwaysFalse() ) /////////////////////////////////////////////////////////////////////////////// #define INTERNAL_CATCH_THROWS( macroName, resultDisposition, matcher, expr ) \ do { \ Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(expr), resultDisposition, CATCH_INTERNAL_STRINGIFY(matcher) ); \ if( __catchResult.allowThrows() ) \ try { \ static_cast(expr); \ __catchResult.captureResult( Catch::ResultWas::DidntThrowException ); \ } \ catch( ... ) { \ __catchResult.captureExpectedException( matcher ); \ } \ else \ __catchResult.captureResult( Catch::ResultWas::Ok ); \ INTERNAL_CATCH_REACT( __catchResult ) \ } while( Catch::alwaysFalse() ) /////////////////////////////////////////////////////////////////////////////// #define INTERNAL_CATCH_THROWS_AS( macroName, exceptionType, resultDisposition, expr ) \ do { \ Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(expr) ", " CATCH_INTERNAL_STRINGIFY(exceptionType), resultDisposition ); \ if( __catchResult.allowThrows() ) \ try { \ static_cast(expr); \ __catchResult.captureResult( Catch::ResultWas::DidntThrowException ); \ } \ catch( exceptionType ) { \ __catchResult.captureResult( Catch::ResultWas::Ok ); \ } \ catch( ... ) { \ __catchResult.useActiveException( resultDisposition ); \ } \ else \ __catchResult.captureResult( Catch::ResultWas::Ok ); \ INTERNAL_CATCH_REACT( __catchResult ) \ } while( Catch::alwaysFalse() ) /////////////////////////////////////////////////////////////////////////////// #ifdef CATCH_CONFIG_VARIADIC_MACROS #define INTERNAL_CATCH_MSG( macroName, messageType, resultDisposition, ... ) \ do { \ Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, "", resultDisposition ); \ __catchResult << __VA_ARGS__ + ::Catch::StreamEndStop(); \ __catchResult.captureResult( messageType ); \ INTERNAL_CATCH_REACT( __catchResult ) \ } while( Catch::alwaysFalse() ) #else #define INTERNAL_CATCH_MSG( macroName, messageType, resultDisposition, log ) \ do { \ Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, "", resultDisposition ); \ __catchResult << log + ::Catch::StreamEndStop(); \ __catchResult.captureResult( messageType ); \ INTERNAL_CATCH_REACT( __catchResult ) \ } while( Catch::alwaysFalse() ) #endif /////////////////////////////////////////////////////////////////////////////// #define INTERNAL_CATCH_INFO( macroName, log ) \ Catch::ScopedMessage INTERNAL_CATCH_UNIQUE_NAME( scopedMessage ) = Catch::MessageBuilder( macroName, CATCH_INTERNAL_LINEINFO, Catch::ResultWas::Info ) << log; /////////////////////////////////////////////////////////////////////////////// #define INTERNAL_CHECK_THAT( macroName, matcher, resultDisposition, arg ) \ do { \ Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(arg) ", " CATCH_INTERNAL_STRINGIFY(matcher), resultDisposition ); \ try { \ __catchResult.captureMatch( arg, matcher, CATCH_INTERNAL_STRINGIFY(matcher) ); \ } catch( ... ) { \ __catchResult.useActiveException( resultDisposition | Catch::ResultDisposition::ContinueOnFailure ); \ } \ INTERNAL_CATCH_REACT( __catchResult ) \ } while( Catch::alwaysFalse() ) // #included from: internal/catch_section.h #define TWOBLUECUBES_CATCH_SECTION_H_INCLUDED // #included from: catch_section_info.h #define TWOBLUECUBES_CATCH_SECTION_INFO_H_INCLUDED // #included from: catch_totals.hpp #define TWOBLUECUBES_CATCH_TOTALS_HPP_INCLUDED #include namespace Catch { struct Counts { Counts() : passed( 0 ), failed( 0 ), failedButOk( 0 ) {} Counts operator - ( Counts const& other ) const { Counts diff; diff.passed = passed - other.passed; diff.failed = failed - other.failed; diff.failedButOk = failedButOk - other.failedButOk; return diff; } Counts& operator += ( Counts const& other ) { passed += other.passed; failed += other.failed; failedButOk += other.failedButOk; return *this; } std::size_t total() const { return passed + failed + failedButOk; } bool allPassed() const { return failed == 0 && failedButOk == 0; } bool allOk() const { return failed == 0; } std::size_t passed; std::size_t failed; std::size_t failedButOk; }; struct Totals { Totals operator - ( Totals const& other ) const { Totals diff; diff.assertions = assertions - other.assertions; diff.testCases = testCases - other.testCases; return diff; } Totals delta( Totals const& prevTotals ) const { Totals diff = *this - prevTotals; if( diff.assertions.failed > 0 ) ++diff.testCases.failed; else if( diff.assertions.failedButOk > 0 ) ++diff.testCases.failedButOk; else ++diff.testCases.passed; return diff; } Totals& operator += ( Totals const& other ) { assertions += other.assertions; testCases += other.testCases; return *this; } Counts assertions; Counts testCases; }; } #include namespace Catch { struct SectionInfo { SectionInfo ( SourceLineInfo const& _lineInfo, std::string const& _name, std::string const& _description = std::string() ); std::string name; std::string description; SourceLineInfo lineInfo; }; struct SectionEndInfo { SectionEndInfo( SectionInfo const& _sectionInfo, Counts const& _prevAssertions, double _durationInSeconds ) : sectionInfo( _sectionInfo ), prevAssertions( _prevAssertions ), durationInSeconds( _durationInSeconds ) {} SectionInfo sectionInfo; Counts prevAssertions; double durationInSeconds; }; } // end namespace Catch // #included from: catch_timer.h #define TWOBLUECUBES_CATCH_TIMER_H_INCLUDED #ifdef _MSC_VER namespace Catch { typedef unsigned long long UInt64; } #else #include namespace Catch { typedef uint64_t UInt64; } #endif namespace Catch { class Timer { public: Timer() : m_ticks( 0 ) {} void start(); unsigned int getElapsedMicroseconds() const; unsigned int getElapsedMilliseconds() const; double getElapsedSeconds() const; private: UInt64 m_ticks; }; } // namespace Catch #include namespace Catch { class Section : NonCopyable { public: Section( SectionInfo const& info ); ~Section(); // This indicates whether the section should be executed or not operator bool() const; private: SectionInfo m_info; std::string m_name; Counts m_assertions; bool m_sectionIncluded; Timer m_timer; }; } // end namespace Catch #ifdef CATCH_CONFIG_VARIADIC_MACROS #define INTERNAL_CATCH_SECTION( ... ) \ if( Catch::Section const& INTERNAL_CATCH_UNIQUE_NAME( catch_internal_Section ) = Catch::SectionInfo( CATCH_INTERNAL_LINEINFO, __VA_ARGS__ ) ) #else #define INTERNAL_CATCH_SECTION( name, desc ) \ if( Catch::Section const& INTERNAL_CATCH_UNIQUE_NAME( catch_internal_Section ) = Catch::SectionInfo( CATCH_INTERNAL_LINEINFO, name, desc ) ) #endif // #included from: internal/catch_generators.hpp #define TWOBLUECUBES_CATCH_GENERATORS_HPP_INCLUDED #include #include #include namespace Catch { template struct IGenerator { virtual ~IGenerator() {} virtual T getValue( std::size_t index ) const = 0; virtual std::size_t size () const = 0; }; template class BetweenGenerator : public IGenerator { public: BetweenGenerator( T from, T to ) : m_from( from ), m_to( to ){} virtual T getValue( std::size_t index ) const { return m_from+static_cast( index ); } virtual std::size_t size() const { return static_cast( 1+m_to-m_from ); } private: T m_from; T m_to; }; template class ValuesGenerator : public IGenerator { public: ValuesGenerator(){} void add( T value ) { m_values.push_back( value ); } virtual T getValue( std::size_t index ) const { return m_values[index]; } virtual std::size_t size() const { return m_values.size(); } private: std::vector m_values; }; template class CompositeGenerator { public: CompositeGenerator() : m_totalSize( 0 ) {} // *** Move semantics, similar to auto_ptr *** CompositeGenerator( CompositeGenerator& other ) : m_fileInfo( other.m_fileInfo ), m_totalSize( 0 ) { move( other ); } CompositeGenerator& setFileInfo( const char* fileInfo ) { m_fileInfo = fileInfo; return *this; } ~CompositeGenerator() { deleteAll( m_composed ); } operator T () const { size_t overallIndex = getCurrentContext().getGeneratorIndex( m_fileInfo, m_totalSize ); typename std::vector*>::const_iterator it = m_composed.begin(); typename std::vector*>::const_iterator itEnd = m_composed.end(); for( size_t index = 0; it != itEnd; ++it ) { const IGenerator* generator = *it; if( overallIndex >= index && overallIndex < index + generator->size() ) { return generator->getValue( overallIndex-index ); } index += generator->size(); } CATCH_INTERNAL_ERROR( "Indexed past end of generated range" ); return T(); // Suppress spurious "not all control paths return a value" warning in Visual Studio - if you know how to fix this please do so } void add( const IGenerator* generator ) { m_totalSize += generator->size(); m_composed.push_back( generator ); } CompositeGenerator& then( CompositeGenerator& other ) { move( other ); return *this; } CompositeGenerator& then( T value ) { ValuesGenerator* valuesGen = new ValuesGenerator(); valuesGen->add( value ); add( valuesGen ); return *this; } private: void move( CompositeGenerator& other ) { m_composed.insert( m_composed.end(), other.m_composed.begin(), other.m_composed.end() ); m_totalSize += other.m_totalSize; other.m_composed.clear(); } std::vector*> m_composed; std::string m_fileInfo; size_t m_totalSize; }; namespace Generators { template CompositeGenerator between( T from, T to ) { CompositeGenerator generators; generators.add( new BetweenGenerator( from, to ) ); return generators; } template CompositeGenerator values( T val1, T val2 ) { CompositeGenerator generators; ValuesGenerator* valuesGen = new ValuesGenerator(); valuesGen->add( val1 ); valuesGen->add( val2 ); generators.add( valuesGen ); return generators; } template CompositeGenerator values( T val1, T val2, T val3 ){ CompositeGenerator generators; ValuesGenerator* valuesGen = new ValuesGenerator(); valuesGen->add( val1 ); valuesGen->add( val2 ); valuesGen->add( val3 ); generators.add( valuesGen ); return generators; } template CompositeGenerator values( T val1, T val2, T val3, T val4 ) { CompositeGenerator generators; ValuesGenerator* valuesGen = new ValuesGenerator(); valuesGen->add( val1 ); valuesGen->add( val2 ); valuesGen->add( val3 ); valuesGen->add( val4 ); generators.add( valuesGen ); return generators; } } // end namespace Generators using namespace Generators; } // end namespace Catch #define INTERNAL_CATCH_LINESTR2( line ) #line #define INTERNAL_CATCH_LINESTR( line ) INTERNAL_CATCH_LINESTR2( line ) #define INTERNAL_CATCH_GENERATE( expr ) expr.setFileInfo( __FILE__ "(" INTERNAL_CATCH_LINESTR( __LINE__ ) ")" ) // #included from: internal/catch_interfaces_exception.h #define TWOBLUECUBES_CATCH_INTERFACES_EXCEPTION_H_INCLUDED #include #include // #included from: catch_interfaces_registry_hub.h #define TWOBLUECUBES_CATCH_INTERFACES_REGISTRY_HUB_H_INCLUDED #include namespace Catch { class TestCase; struct ITestCaseRegistry; struct IExceptionTranslatorRegistry; struct IExceptionTranslator; struct IReporterRegistry; struct IReporterFactory; struct ITagAliasRegistry; struct IRegistryHub { virtual ~IRegistryHub(); virtual IReporterRegistry const& getReporterRegistry() const = 0; virtual ITestCaseRegistry const& getTestCaseRegistry() const = 0; virtual ITagAliasRegistry const& getTagAliasRegistry() const = 0; virtual IExceptionTranslatorRegistry& getExceptionTranslatorRegistry() = 0; }; struct IMutableRegistryHub { virtual ~IMutableRegistryHub(); virtual void registerReporter( std::string const& name, Ptr const& factory ) = 0; virtual void registerListener( Ptr const& factory ) = 0; virtual void registerTest( TestCase const& testInfo ) = 0; virtual void registerTranslator( const IExceptionTranslator* translator ) = 0; virtual void registerTagAlias( std::string const& alias, std::string const& tag, SourceLineInfo const& lineInfo ) = 0; }; IRegistryHub& getRegistryHub(); IMutableRegistryHub& getMutableRegistryHub(); void cleanUp(); std::string translateActiveException(); } namespace Catch { typedef std::string(*exceptionTranslateFunction)(); struct IExceptionTranslator; typedef std::vector ExceptionTranslators; struct IExceptionTranslator { virtual ~IExceptionTranslator(); virtual std::string translate( ExceptionTranslators::const_iterator it, ExceptionTranslators::const_iterator itEnd ) const = 0; }; struct IExceptionTranslatorRegistry { virtual ~IExceptionTranslatorRegistry(); virtual std::string translateActiveException() const = 0; }; class ExceptionTranslatorRegistrar { template class ExceptionTranslator : public IExceptionTranslator { public: ExceptionTranslator( std::string(*translateFunction)( T& ) ) : m_translateFunction( translateFunction ) {} virtual std::string translate( ExceptionTranslators::const_iterator it, ExceptionTranslators::const_iterator itEnd ) const CATCH_OVERRIDE { try { if( it == itEnd ) throw; else return (*it)->translate( it+1, itEnd ); } catch( T& ex ) { return m_translateFunction( ex ); } } protected: std::string(*m_translateFunction)( T& ); }; public: template ExceptionTranslatorRegistrar( std::string(*translateFunction)( T& ) ) { getMutableRegistryHub().registerTranslator ( new ExceptionTranslator( translateFunction ) ); } }; } /////////////////////////////////////////////////////////////////////////////// #define INTERNAL_CATCH_TRANSLATE_EXCEPTION2( translatorName, signature ) \ static std::string translatorName( signature ); \ namespace{ Catch::ExceptionTranslatorRegistrar INTERNAL_CATCH_UNIQUE_NAME( catch_internal_ExceptionRegistrar )( &translatorName ); }\ static std::string translatorName( signature ) #define INTERNAL_CATCH_TRANSLATE_EXCEPTION( signature ) INTERNAL_CATCH_TRANSLATE_EXCEPTION2( INTERNAL_CATCH_UNIQUE_NAME( catch_internal_ExceptionTranslator ), signature ) // #included from: internal/catch_approx.hpp #define TWOBLUECUBES_CATCH_APPROX_HPP_INCLUDED #include #include #if defined(CATCH_CONFIG_CPP11_TYPE_TRAITS) #include #endif namespace Catch { namespace Detail { class Approx { public: explicit Approx ( double value ) : m_epsilon( std::numeric_limits::epsilon()*100 ), m_margin( 0.0 ), m_scale( 1.0 ), m_value( value ) {} static Approx custom() { return Approx( 0 ); } #if defined(CATCH_CONFIG_CPP11_TYPE_TRAITS) template ::value>::type> Approx operator()( T value ) { Approx approx( static_cast(value) ); approx.epsilon( m_epsilon ); approx.margin( m_margin ); approx.scale( m_scale ); return approx; } template ::value>::type> explicit Approx( T value ): Approx(static_cast(value)) {} template ::value>::type> friend bool operator == ( const T& lhs, Approx const& rhs ) { // Thanks to Richard Harris for his help refining this formula auto lhs_v = double(lhs); bool relativeOK = std::fabs(lhs_v - rhs.m_value) < rhs.m_epsilon * (rhs.m_scale + (std::max)(std::fabs(lhs_v), std::fabs(rhs.m_value))); if (relativeOK) { return true; } return std::fabs(lhs_v - rhs.m_value) <= rhs.m_margin; } template ::value>::type> friend bool operator == ( Approx const& lhs, const T& rhs ) { return operator==( rhs, lhs ); } template ::value>::type> friend bool operator != ( T lhs, Approx const& rhs ) { return !operator==( lhs, rhs ); } template ::value>::type> friend bool operator != ( Approx const& lhs, T rhs ) { return !operator==( rhs, lhs ); } template ::value>::type> friend bool operator <= ( T lhs, Approx const& rhs ) { return double(lhs) < rhs.m_value || lhs == rhs; } template ::value>::type> friend bool operator <= ( Approx const& lhs, T rhs ) { return lhs.m_value < double(rhs) || lhs == rhs; } template ::value>::type> friend bool operator >= ( T lhs, Approx const& rhs ) { return double(lhs) > rhs.m_value || lhs == rhs; } template ::value>::type> friend bool operator >= ( Approx const& lhs, T rhs ) { return lhs.m_value > double(rhs) || lhs == rhs; } template ::value>::type> Approx& epsilon( T newEpsilon ) { m_epsilon = double(newEpsilon); return *this; } template ::value>::type> Approx& margin( T newMargin ) { m_margin = double(newMargin); return *this; } template ::value>::type> Approx& scale( T newScale ) { m_scale = double(newScale); return *this; } #else Approx operator()( double value ) { Approx approx( value ); approx.epsilon( m_epsilon ); approx.margin( m_margin ); approx.scale( m_scale ); return approx; } friend bool operator == ( double lhs, Approx const& rhs ) { // Thanks to Richard Harris for his help refining this formula bool relativeOK = std::fabs( lhs - rhs.m_value ) < rhs.m_epsilon * (rhs.m_scale + (std::max)( std::fabs(lhs), std::fabs(rhs.m_value) ) ); if (relativeOK) { return true; } return std::fabs(lhs - rhs.m_value) <= rhs.m_margin; } friend bool operator == ( Approx const& lhs, double rhs ) { return operator==( rhs, lhs ); } friend bool operator != ( double lhs, Approx const& rhs ) { return !operator==( lhs, rhs ); } friend bool operator != ( Approx const& lhs, double rhs ) { return !operator==( rhs, lhs ); } friend bool operator <= ( double lhs, Approx const& rhs ) { return lhs < rhs.m_value || lhs == rhs; } friend bool operator <= ( Approx const& lhs, double rhs ) { return lhs.m_value < rhs || lhs == rhs; } friend bool operator >= ( double lhs, Approx const& rhs ) { return lhs > rhs.m_value || lhs == rhs; } friend bool operator >= ( Approx const& lhs, double rhs ) { return lhs.m_value > rhs || lhs == rhs; } Approx& epsilon( double newEpsilon ) { m_epsilon = newEpsilon; return *this; } Approx& margin( double newMargin ) { m_margin = newMargin; return *this; } Approx& scale( double newScale ) { m_scale = newScale; return *this; } #endif std::string toString() const { std::ostringstream oss; oss << "Approx( " << Catch::toString( m_value ) << " )"; return oss.str(); } private: double m_epsilon; double m_margin; double m_scale; double m_value; }; } template<> inline std::string toString( Detail::Approx const& value ) { return value.toString(); } } // end namespace Catch // #included from: internal/catch_matchers_string.h #define TWOBLUECUBES_CATCH_MATCHERS_STRING_H_INCLUDED namespace Catch { namespace Matchers { namespace StdString { struct CasedString { CasedString( std::string const& str, CaseSensitive::Choice caseSensitivity ); std::string adjustString( std::string const& str ) const; std::string caseSensitivitySuffix() const; CaseSensitive::Choice m_caseSensitivity; std::string m_str; }; struct StringMatcherBase : MatcherBase { StringMatcherBase( std::string const& operation, CasedString const& comparator ); virtual std::string describe() const CATCH_OVERRIDE; CasedString m_comparator; std::string m_operation; }; struct EqualsMatcher : StringMatcherBase { EqualsMatcher( CasedString const& comparator ); virtual bool match( std::string const& source ) const CATCH_OVERRIDE; }; struct ContainsMatcher : StringMatcherBase { ContainsMatcher( CasedString const& comparator ); virtual bool match( std::string const& source ) const CATCH_OVERRIDE; }; struct StartsWithMatcher : StringMatcherBase { StartsWithMatcher( CasedString const& comparator ); virtual bool match( std::string const& source ) const CATCH_OVERRIDE; }; struct EndsWithMatcher : StringMatcherBase { EndsWithMatcher( CasedString const& comparator ); virtual bool match( std::string const& source ) const CATCH_OVERRIDE; }; } // namespace StdString // The following functions create the actual matcher objects. // This allows the types to be inferred StdString::EqualsMatcher Equals( std::string const& str, CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes ); StdString::ContainsMatcher Contains( std::string const& str, CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes ); StdString::EndsWithMatcher EndsWith( std::string const& str, CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes ); StdString::StartsWithMatcher StartsWith( std::string const& str, CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes ); } // namespace Matchers } // namespace Catch // #included from: internal/catch_matchers_vector.h #define TWOBLUECUBES_CATCH_MATCHERS_VECTOR_H_INCLUDED namespace Catch { namespace Matchers { namespace Vector { template struct ContainsElementMatcher : MatcherBase, T> { ContainsElementMatcher(T const &comparator) : m_comparator( comparator) {} bool match(std::vector const &v) const CATCH_OVERRIDE { return std::find(v.begin(), v.end(), m_comparator) != v.end(); } virtual std::string describe() const CATCH_OVERRIDE { return "Contains: " + Catch::toString( m_comparator ); } T const& m_comparator; }; template struct ContainsMatcher : MatcherBase, std::vector > { ContainsMatcher(std::vector const &comparator) : m_comparator( comparator ) {} bool match(std::vector const &v) const CATCH_OVERRIDE { // !TBD: see note in EqualsMatcher if (m_comparator.size() > v.size()) return false; for (size_t i = 0; i < m_comparator.size(); ++i) if (std::find(v.begin(), v.end(), m_comparator[i]) == v.end()) return false; return true; } virtual std::string describe() const CATCH_OVERRIDE { return "Contains: " + Catch::toString( m_comparator ); } std::vector const& m_comparator; }; template struct EqualsMatcher : MatcherBase, std::vector > { EqualsMatcher(std::vector const &comparator) : m_comparator( comparator ) {} bool match(std::vector const &v) const CATCH_OVERRIDE { // !TBD: This currently works if all elements can be compared using != // - a more general approach would be via a compare template that defaults // to using !=. but could be specialised for, e.g. std::vector etc // - then just call that directly if (m_comparator.size() != v.size()) return false; for (size_t i = 0; i < v.size(); ++i) if (m_comparator[i] != v[i]) return false; return true; } virtual std::string describe() const CATCH_OVERRIDE { return "Equals: " + Catch::toString( m_comparator ); } std::vector const& m_comparator; }; } // namespace Vector // The following functions create the actual matcher objects. // This allows the types to be inferred template Vector::ContainsMatcher Contains( std::vector const& comparator ) { return Vector::ContainsMatcher( comparator ); } template Vector::ContainsElementMatcher VectorContains( T const& comparator ) { return Vector::ContainsElementMatcher( comparator ); } template Vector::EqualsMatcher Equals( std::vector const& comparator ) { return Vector::EqualsMatcher( comparator ); } } // namespace Matchers } // namespace Catch // #included from: internal/catch_interfaces_tag_alias_registry.h #define TWOBLUECUBES_CATCH_INTERFACES_TAG_ALIAS_REGISTRY_H_INCLUDED // #included from: catch_tag_alias.h #define TWOBLUECUBES_CATCH_TAG_ALIAS_H_INCLUDED #include namespace Catch { struct TagAlias { TagAlias( std::string const& _tag, SourceLineInfo _lineInfo ) : tag( _tag ), lineInfo( _lineInfo ) {} std::string tag; SourceLineInfo lineInfo; }; struct RegistrarForTagAliases { RegistrarForTagAliases( char const* alias, char const* tag, SourceLineInfo const& lineInfo ); }; } // end namespace Catch #define CATCH_REGISTER_TAG_ALIAS( alias, spec ) namespace{ Catch::RegistrarForTagAliases INTERNAL_CATCH_UNIQUE_NAME( AutoRegisterTagAlias )( alias, spec, CATCH_INTERNAL_LINEINFO ); } // #included from: catch_option.hpp #define TWOBLUECUBES_CATCH_OPTION_HPP_INCLUDED namespace Catch { // An optional type template class Option { public: Option() : nullableValue( CATCH_NULL ) {} Option( T const& _value ) : nullableValue( new( storage ) T( _value ) ) {} Option( Option const& _other ) : nullableValue( _other ? new( storage ) T( *_other ) : CATCH_NULL ) {} ~Option() { reset(); } Option& operator= ( Option const& _other ) { if( &_other != this ) { reset(); if( _other ) nullableValue = new( storage ) T( *_other ); } return *this; } Option& operator = ( T const& _value ) { reset(); nullableValue = new( storage ) T( _value ); return *this; } void reset() { if( nullableValue ) nullableValue->~T(); nullableValue = CATCH_NULL; } T& operator*() { return *nullableValue; } T const& operator*() const { return *nullableValue; } T* operator->() { return nullableValue; } const T* operator->() const { return nullableValue; } T valueOr( T const& defaultValue ) const { return nullableValue ? *nullableValue : defaultValue; } bool some() const { return nullableValue != CATCH_NULL; } bool none() const { return nullableValue == CATCH_NULL; } bool operator !() const { return nullableValue == CATCH_NULL; } operator SafeBool::type() const { return SafeBool::makeSafe( some() ); } private: T *nullableValue; union { char storage[sizeof(T)]; // These are here to force alignment for the storage long double dummy1; void (*dummy2)(); long double dummy3; #ifdef CATCH_CONFIG_CPP11_LONG_LONG long long dummy4; #endif }; }; } // end namespace Catch namespace Catch { struct ITagAliasRegistry { virtual ~ITagAliasRegistry(); virtual Option find( std::string const& alias ) const = 0; virtual std::string expandAliases( std::string const& unexpandedTestSpec ) const = 0; static ITagAliasRegistry const& get(); }; } // end namespace Catch // These files are included here so the single_include script doesn't put them // in the conditionally compiled sections // #included from: internal/catch_test_case_info.h #define TWOBLUECUBES_CATCH_TEST_CASE_INFO_H_INCLUDED #include #include #ifdef __clang__ #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wpadded" #endif namespace Catch { struct ITestCase; struct TestCaseInfo { enum SpecialProperties{ None = 0, IsHidden = 1 << 1, ShouldFail = 1 << 2, MayFail = 1 << 3, Throws = 1 << 4, NonPortable = 1 << 5 }; TestCaseInfo( std::string const& _name, std::string const& _className, std::string const& _description, std::set const& _tags, SourceLineInfo const& _lineInfo ); TestCaseInfo( TestCaseInfo const& other ); friend void setTags( TestCaseInfo& testCaseInfo, std::set const& tags ); bool isHidden() const; bool throws() const; bool okToFail() const; bool expectedToFail() const; std::string name; std::string className; std::string description; std::set tags; std::set lcaseTags; std::string tagsAsString; SourceLineInfo lineInfo; SpecialProperties properties; }; class TestCase : public TestCaseInfo { public: TestCase( ITestCase* testCase, TestCaseInfo const& info ); TestCase( TestCase const& other ); TestCase withName( std::string const& _newName ) const; void invoke() const; TestCaseInfo const& getTestCaseInfo() const; void swap( TestCase& other ); bool operator == ( TestCase const& other ) const; bool operator < ( TestCase const& other ) const; TestCase& operator = ( TestCase const& other ); private: Ptr test; }; TestCase makeTestCase( ITestCase* testCase, std::string const& className, std::string const& name, std::string const& description, SourceLineInfo const& lineInfo ); } #ifdef __clang__ #pragma clang diagnostic pop #endif #ifdef __OBJC__ // #included from: internal/catch_objc.hpp #define TWOBLUECUBES_CATCH_OBJC_HPP_INCLUDED #import #include // NB. Any general catch headers included here must be included // in catch.hpp first to make sure they are included by the single // header for non obj-usage /////////////////////////////////////////////////////////////////////////////// // This protocol is really only here for (self) documenting purposes, since // all its methods are optional. @protocol OcFixture @optional -(void) setUp; -(void) tearDown; @end namespace Catch { class OcMethod : public SharedImpl { public: OcMethod( Class cls, SEL sel ) : m_cls( cls ), m_sel( sel ) {} virtual void invoke() const { id obj = [[m_cls alloc] init]; performOptionalSelector( obj, @selector(setUp) ); performOptionalSelector( obj, m_sel ); performOptionalSelector( obj, @selector(tearDown) ); arcSafeRelease( obj ); } private: virtual ~OcMethod() {} Class m_cls; SEL m_sel; }; namespace Detail{ inline std::string getAnnotation( Class cls, std::string const& annotationName, std::string const& testCaseName ) { NSString* selStr = [[NSString alloc] initWithFormat:@"Catch_%s_%s", annotationName.c_str(), testCaseName.c_str()]; SEL sel = NSSelectorFromString( selStr ); arcSafeRelease( selStr ); id value = performOptionalSelector( cls, sel ); if( value ) return [(NSString*)value UTF8String]; return ""; } } inline size_t registerTestMethods() { size_t noTestMethods = 0; int noClasses = objc_getClassList( CATCH_NULL, 0 ); Class* classes = (CATCH_UNSAFE_UNRETAINED Class *)malloc( sizeof(Class) * noClasses); objc_getClassList( classes, noClasses ); for( int c = 0; c < noClasses; c++ ) { Class cls = classes[c]; { u_int count; Method* methods = class_copyMethodList( cls, &count ); for( u_int m = 0; m < count ; m++ ) { SEL selector = method_getName(methods[m]); std::string methodName = sel_getName(selector); if( startsWith( methodName, "Catch_TestCase_" ) ) { std::string testCaseName = methodName.substr( 15 ); std::string name = Detail::getAnnotation( cls, "Name", testCaseName ); std::string desc = Detail::getAnnotation( cls, "Description", testCaseName ); const char* className = class_getName( cls ); getMutableRegistryHub().registerTest( makeTestCase( new OcMethod( cls, selector ), className, name.c_str(), desc.c_str(), SourceLineInfo() ) ); noTestMethods++; } } free(methods); } } return noTestMethods; } namespace Matchers { namespace Impl { namespace NSStringMatchers { struct StringHolder : MatcherBase{ StringHolder( NSString* substr ) : m_substr( [substr copy] ){} StringHolder( StringHolder const& other ) : m_substr( [other.m_substr copy] ){} StringHolder() { arcSafeRelease( m_substr ); } virtual bool match( NSString* arg ) const CATCH_OVERRIDE { return false; } NSString* m_substr; }; struct Equals : StringHolder { Equals( NSString* substr ) : StringHolder( substr ){} virtual bool match( NSString* str ) const CATCH_OVERRIDE { return (str != nil || m_substr == nil ) && [str isEqualToString:m_substr]; } virtual std::string describe() const CATCH_OVERRIDE { return "equals string: " + Catch::toString( m_substr ); } }; struct Contains : StringHolder { Contains( NSString* substr ) : StringHolder( substr ){} virtual bool match( NSString* str ) const { return (str != nil || m_substr == nil ) && [str rangeOfString:m_substr].location != NSNotFound; } virtual std::string describe() const CATCH_OVERRIDE { return "contains string: " + Catch::toString( m_substr ); } }; struct StartsWith : StringHolder { StartsWith( NSString* substr ) : StringHolder( substr ){} virtual bool match( NSString* str ) const { return (str != nil || m_substr == nil ) && [str rangeOfString:m_substr].location == 0; } virtual std::string describe() const CATCH_OVERRIDE { return "starts with: " + Catch::toString( m_substr ); } }; struct EndsWith : StringHolder { EndsWith( NSString* substr ) : StringHolder( substr ){} virtual bool match( NSString* str ) const { return (str != nil || m_substr == nil ) && [str rangeOfString:m_substr].location == [str length] - [m_substr length]; } virtual std::string describe() const CATCH_OVERRIDE { return "ends with: " + Catch::toString( m_substr ); } }; } // namespace NSStringMatchers } // namespace Impl inline Impl::NSStringMatchers::Equals Equals( NSString* substr ){ return Impl::NSStringMatchers::Equals( substr ); } inline Impl::NSStringMatchers::Contains Contains( NSString* substr ){ return Impl::NSStringMatchers::Contains( substr ); } inline Impl::NSStringMatchers::StartsWith StartsWith( NSString* substr ){ return Impl::NSStringMatchers::StartsWith( substr ); } inline Impl::NSStringMatchers::EndsWith EndsWith( NSString* substr ){ return Impl::NSStringMatchers::EndsWith( substr ); } } // namespace Matchers using namespace Matchers; } // namespace Catch /////////////////////////////////////////////////////////////////////////////// #define OC_TEST_CASE( name, desc )\ +(NSString*) INTERNAL_CATCH_UNIQUE_NAME( Catch_Name_test ) \ {\ return @ name; \ }\ +(NSString*) INTERNAL_CATCH_UNIQUE_NAME( Catch_Description_test ) \ { \ return @ desc; \ } \ -(void) INTERNAL_CATCH_UNIQUE_NAME( Catch_TestCase_test ) #endif #ifdef CATCH_IMPL // !TBD: Move the leak detector code into a separate header #ifdef CATCH_CONFIG_WINDOWS_CRTDBG #include class LeakDetector { public: LeakDetector() { int flag = _CrtSetDbgFlag(_CRTDBG_REPORT_FLAG); flag |= _CRTDBG_LEAK_CHECK_DF; flag |= _CRTDBG_ALLOC_MEM_DF; _CrtSetDbgFlag(flag); _CrtSetReportMode(_CRT_WARN, _CRTDBG_MODE_FILE | _CRTDBG_MODE_DEBUG); _CrtSetReportFile(_CRT_WARN, _CRTDBG_FILE_STDERR); // Change this to leaking allocation's number to break there _CrtSetBreakAlloc(-1); } }; #else class LeakDetector {}; #endif LeakDetector leakDetector; // #included from: internal/catch_impl.hpp #define TWOBLUECUBES_CATCH_IMPL_HPP_INCLUDED // Collect all the implementation files together here // These are the equivalent of what would usually be cpp files #ifdef __clang__ #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wweak-vtables" #endif // #included from: ../catch_session.hpp #define TWOBLUECUBES_CATCH_RUNNER_HPP_INCLUDED // #included from: internal/catch_commandline.hpp #define TWOBLUECUBES_CATCH_COMMANDLINE_HPP_INCLUDED // #included from: catch_config.hpp #define TWOBLUECUBES_CATCH_CONFIG_HPP_INCLUDED // #included from: catch_test_spec_parser.hpp #define TWOBLUECUBES_CATCH_TEST_SPEC_PARSER_HPP_INCLUDED #ifdef __clang__ #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wpadded" #endif // #included from: catch_test_spec.hpp #define TWOBLUECUBES_CATCH_TEST_SPEC_HPP_INCLUDED #ifdef __clang__ #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wpadded" #endif // #included from: catch_wildcard_pattern.hpp #define TWOBLUECUBES_CATCH_WILDCARD_PATTERN_HPP_INCLUDED #include namespace Catch { class WildcardPattern { enum WildcardPosition { NoWildcard = 0, WildcardAtStart = 1, WildcardAtEnd = 2, WildcardAtBothEnds = WildcardAtStart | WildcardAtEnd }; public: WildcardPattern( std::string const& pattern, CaseSensitive::Choice caseSensitivity ) : m_caseSensitivity( caseSensitivity ), m_wildcard( NoWildcard ), m_pattern( adjustCase( pattern ) ) { if( startsWith( m_pattern, '*' ) ) { m_pattern = m_pattern.substr( 1 ); m_wildcard = WildcardAtStart; } if( endsWith( m_pattern, '*' ) ) { m_pattern = m_pattern.substr( 0, m_pattern.size()-1 ); m_wildcard = static_cast( m_wildcard | WildcardAtEnd ); } } virtual ~WildcardPattern(); virtual bool matches( std::string const& str ) const { switch( m_wildcard ) { case NoWildcard: return m_pattern == adjustCase( str ); case WildcardAtStart: return endsWith( adjustCase( str ), m_pattern ); case WildcardAtEnd: return startsWith( adjustCase( str ), m_pattern ); case WildcardAtBothEnds: return contains( adjustCase( str ), m_pattern ); } #ifdef __clang__ #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wunreachable-code" #endif throw std::logic_error( "Unknown enum" ); #ifdef __clang__ #pragma clang diagnostic pop #endif } private: std::string adjustCase( std::string const& str ) const { return m_caseSensitivity == CaseSensitive::No ? toLower( str ) : str; } CaseSensitive::Choice m_caseSensitivity; WildcardPosition m_wildcard; std::string m_pattern; }; } #include #include namespace Catch { class TestSpec { struct Pattern : SharedImpl<> { virtual ~Pattern(); virtual bool matches( TestCaseInfo const& testCase ) const = 0; }; class NamePattern : public Pattern { public: NamePattern( std::string const& name ) : m_wildcardPattern( toLower( name ), CaseSensitive::No ) {} virtual ~NamePattern(); virtual bool matches( TestCaseInfo const& testCase ) const { return m_wildcardPattern.matches( toLower( testCase.name ) ); } private: WildcardPattern m_wildcardPattern; }; class TagPattern : public Pattern { public: TagPattern( std::string const& tag ) : m_tag( toLower( tag ) ) {} virtual ~TagPattern(); virtual bool matches( TestCaseInfo const& testCase ) const { return testCase.lcaseTags.find( m_tag ) != testCase.lcaseTags.end(); } private: std::string m_tag; }; class ExcludedPattern : public Pattern { public: ExcludedPattern( Ptr const& underlyingPattern ) : m_underlyingPattern( underlyingPattern ) {} virtual ~ExcludedPattern(); virtual bool matches( TestCaseInfo const& testCase ) const { return !m_underlyingPattern->matches( testCase ); } private: Ptr m_underlyingPattern; }; struct Filter { std::vector > m_patterns; bool matches( TestCaseInfo const& testCase ) const { // All patterns in a filter must match for the filter to be a match for( std::vector >::const_iterator it = m_patterns.begin(), itEnd = m_patterns.end(); it != itEnd; ++it ) { if( !(*it)->matches( testCase ) ) return false; } return true; } }; public: bool hasFilters() const { return !m_filters.empty(); } bool matches( TestCaseInfo const& testCase ) const { // A TestSpec matches if any filter matches for( std::vector::const_iterator it = m_filters.begin(), itEnd = m_filters.end(); it != itEnd; ++it ) if( it->matches( testCase ) ) return true; return false; } private: std::vector m_filters; friend class TestSpecParser; }; } #ifdef __clang__ #pragma clang diagnostic pop #endif namespace Catch { class TestSpecParser { enum Mode{ None, Name, QuotedName, Tag, EscapedName }; Mode m_mode; bool m_exclusion; std::size_t m_start, m_pos; std::string m_arg; std::vector m_escapeChars; TestSpec::Filter m_currentFilter; TestSpec m_testSpec; ITagAliasRegistry const* m_tagAliases; public: TestSpecParser( ITagAliasRegistry const& tagAliases ) :m_mode(None), m_exclusion(false), m_start(0), m_pos(0), m_tagAliases( &tagAliases ) {} TestSpecParser& parse( std::string const& arg ) { m_mode = None; m_exclusion = false; m_start = std::string::npos; m_arg = m_tagAliases->expandAliases( arg ); m_escapeChars.clear(); for( m_pos = 0; m_pos < m_arg.size(); ++m_pos ) visitChar( m_arg[m_pos] ); if( m_mode == Name ) addPattern(); return *this; } TestSpec testSpec() { addFilter(); return m_testSpec; } private: void visitChar( char c ) { if( m_mode == None ) { switch( c ) { case ' ': return; case '~': m_exclusion = true; return; case '[': return startNewMode( Tag, ++m_pos ); case '"': return startNewMode( QuotedName, ++m_pos ); case '\\': return escape(); default: startNewMode( Name, m_pos ); break; } } if( m_mode == Name ) { if( c == ',' ) { addPattern(); addFilter(); } else if( c == '[' ) { if( subString() == "exclude:" ) m_exclusion = true; else addPattern(); startNewMode( Tag, ++m_pos ); } else if( c == '\\' ) escape(); } else if( m_mode == EscapedName ) m_mode = Name; else if( m_mode == QuotedName && c == '"' ) addPattern(); else if( m_mode == Tag && c == ']' ) addPattern(); } void startNewMode( Mode mode, std::size_t start ) { m_mode = mode; m_start = start; } void escape() { if( m_mode == None ) m_start = m_pos; m_mode = EscapedName; m_escapeChars.push_back( m_pos ); } std::string subString() const { return m_arg.substr( m_start, m_pos - m_start ); } template void addPattern() { std::string token = subString(); for( size_t i = 0; i < m_escapeChars.size(); ++i ) token = token.substr( 0, m_escapeChars[i]-m_start-i ) + token.substr( m_escapeChars[i]-m_start-i+1 ); m_escapeChars.clear(); if( startsWith( token, "exclude:" ) ) { m_exclusion = true; token = token.substr( 8 ); } if( !token.empty() ) { Ptr pattern = new T( token ); if( m_exclusion ) pattern = new TestSpec::ExcludedPattern( pattern ); m_currentFilter.m_patterns.push_back( pattern ); } m_exclusion = false; m_mode = None; } void addFilter() { if( !m_currentFilter.m_patterns.empty() ) { m_testSpec.m_filters.push_back( m_currentFilter ); m_currentFilter = TestSpec::Filter(); } } }; inline TestSpec parseTestSpec( std::string const& arg ) { return TestSpecParser( ITagAliasRegistry::get() ).parse( arg ).testSpec(); } } // namespace Catch #ifdef __clang__ #pragma clang diagnostic pop #endif // #included from: catch_interfaces_config.h #define TWOBLUECUBES_CATCH_INTERFACES_CONFIG_H_INCLUDED #include #include #include namespace Catch { struct Verbosity { enum Level { NoOutput = 0, Quiet, Normal }; }; struct WarnAbout { enum What { Nothing = 0x00, NoAssertions = 0x01 }; }; struct ShowDurations { enum OrNot { DefaultForReporter, Always, Never }; }; struct RunTests { enum InWhatOrder { InDeclarationOrder, InLexicographicalOrder, InRandomOrder }; }; struct UseColour { enum YesOrNo { Auto, Yes, No }; }; struct WaitForKeypress { enum When { Never, BeforeStart = 1, BeforeExit = 2, BeforeStartAndExit = BeforeStart | BeforeExit }; }; class TestSpec; struct IConfig : IShared { virtual ~IConfig(); virtual bool allowThrows() const = 0; virtual std::ostream& stream() const = 0; virtual std::string name() const = 0; virtual bool includeSuccessfulResults() const = 0; virtual bool shouldDebugBreak() const = 0; virtual bool warnAboutMissingAssertions() const = 0; virtual int abortAfter() const = 0; virtual bool showInvisibles() const = 0; virtual ShowDurations::OrNot showDurations() const = 0; virtual TestSpec const& testSpec() const = 0; virtual RunTests::InWhatOrder runOrder() const = 0; virtual unsigned int rngSeed() const = 0; virtual UseColour::YesOrNo useColour() const = 0; virtual std::vector const& getSectionsToRun() const = 0; }; } // #included from: catch_stream.h #define TWOBLUECUBES_CATCH_STREAM_H_INCLUDED // #included from: catch_streambuf.h #define TWOBLUECUBES_CATCH_STREAMBUF_H_INCLUDED #include namespace Catch { class StreamBufBase : public std::streambuf { public: virtual ~StreamBufBase() CATCH_NOEXCEPT; }; } #include #include #include #include namespace Catch { std::ostream& cout(); std::ostream& cerr(); std::ostream& clog(); struct IStream { virtual ~IStream() CATCH_NOEXCEPT; virtual std::ostream& stream() const = 0; }; class FileStream : public IStream { mutable std::ofstream m_ofs; public: FileStream( std::string const& filename ); virtual ~FileStream() CATCH_NOEXCEPT; public: // IStream virtual std::ostream& stream() const CATCH_OVERRIDE; }; class CoutStream : public IStream { mutable std::ostream m_os; public: CoutStream(); virtual ~CoutStream() CATCH_NOEXCEPT; public: // IStream virtual std::ostream& stream() const CATCH_OVERRIDE; }; class DebugOutStream : public IStream { CATCH_AUTO_PTR( StreamBufBase ) m_streamBuf; mutable std::ostream m_os; public: DebugOutStream(); virtual ~DebugOutStream() CATCH_NOEXCEPT; public: // IStream virtual std::ostream& stream() const CATCH_OVERRIDE; }; } #include #include #include #include #ifndef CATCH_CONFIG_CONSOLE_WIDTH #define CATCH_CONFIG_CONSOLE_WIDTH 80 #endif namespace Catch { struct ConfigData { ConfigData() : listTests( false ), listTags( false ), listReporters( false ), listTestNamesOnly( false ), listExtraInfo( false ), showSuccessfulTests( false ), shouldDebugBreak( false ), noThrow( false ), showHelp( false ), showInvisibles( false ), filenamesAsTags( false ), libIdentify( false ), abortAfter( -1 ), rngSeed( 0 ), verbosity( Verbosity::Normal ), warnings( WarnAbout::Nothing ), showDurations( ShowDurations::DefaultForReporter ), runOrder( RunTests::InDeclarationOrder ), useColour( UseColour::Auto ), waitForKeypress( WaitForKeypress::Never ) {} bool listTests; bool listTags; bool listReporters; bool listTestNamesOnly; bool listExtraInfo; bool showSuccessfulTests; bool shouldDebugBreak; bool noThrow; bool showHelp; bool showInvisibles; bool filenamesAsTags; bool libIdentify; int abortAfter; unsigned int rngSeed; Verbosity::Level verbosity; WarnAbout::What warnings; ShowDurations::OrNot showDurations; RunTests::InWhatOrder runOrder; UseColour::YesOrNo useColour; WaitForKeypress::When waitForKeypress; std::string outputFilename; std::string name; std::string processName; std::vector reporterNames; std::vector testsOrTags; std::vector sectionsToRun; }; class Config : public SharedImpl { private: Config( Config const& other ); Config& operator = ( Config const& other ); virtual void dummy(); public: Config() {} Config( ConfigData const& data ) : m_data( data ), m_stream( openStream() ) { if( !data.testsOrTags.empty() ) { TestSpecParser parser( ITagAliasRegistry::get() ); for( std::size_t i = 0; i < data.testsOrTags.size(); ++i ) parser.parse( data.testsOrTags[i] ); m_testSpec = parser.testSpec(); } } virtual ~Config() {} std::string const& getFilename() const { return m_data.outputFilename ; } bool listTests() const { return m_data.listTests; } bool listTestNamesOnly() const { return m_data.listTestNamesOnly; } bool listTags() const { return m_data.listTags; } bool listReporters() const { return m_data.listReporters; } bool listExtraInfo() const { return m_data.listExtraInfo; } std::string getProcessName() const { return m_data.processName; } std::vector const& getReporterNames() const { return m_data.reporterNames; } std::vector const& getSectionsToRun() const CATCH_OVERRIDE { return m_data.sectionsToRun; } virtual TestSpec const& testSpec() const CATCH_OVERRIDE { return m_testSpec; } bool showHelp() const { return m_data.showHelp; } // IConfig interface virtual bool allowThrows() const CATCH_OVERRIDE { return !m_data.noThrow; } virtual std::ostream& stream() const CATCH_OVERRIDE { return m_stream->stream(); } virtual std::string name() const CATCH_OVERRIDE { return m_data.name.empty() ? m_data.processName : m_data.name; } virtual bool includeSuccessfulResults() const CATCH_OVERRIDE { return m_data.showSuccessfulTests; } virtual bool warnAboutMissingAssertions() const CATCH_OVERRIDE { return m_data.warnings & WarnAbout::NoAssertions; } virtual ShowDurations::OrNot showDurations() const CATCH_OVERRIDE { return m_data.showDurations; } virtual RunTests::InWhatOrder runOrder() const CATCH_OVERRIDE { return m_data.runOrder; } virtual unsigned int rngSeed() const CATCH_OVERRIDE { return m_data.rngSeed; } virtual UseColour::YesOrNo useColour() const CATCH_OVERRIDE { return m_data.useColour; } virtual bool shouldDebugBreak() const CATCH_OVERRIDE { return m_data.shouldDebugBreak; } virtual int abortAfter() const CATCH_OVERRIDE { return m_data.abortAfter; } virtual bool showInvisibles() const CATCH_OVERRIDE { return m_data.showInvisibles; } private: IStream const* openStream() { if( m_data.outputFilename.empty() ) return new CoutStream(); else if( m_data.outputFilename[0] == '%' ) { if( m_data.outputFilename == "%debug" ) return new DebugOutStream(); else throw std::domain_error( "Unrecognised stream: " + m_data.outputFilename ); } else return new FileStream( m_data.outputFilename ); } ConfigData m_data; CATCH_AUTO_PTR( IStream const ) m_stream; TestSpec m_testSpec; }; } // end namespace Catch // #included from: catch_clara.h #define TWOBLUECUBES_CATCH_CLARA_H_INCLUDED // Use Catch's value for console width (store Clara's off to the side, if present) #ifdef CLARA_CONFIG_CONSOLE_WIDTH #define CATCH_TEMP_CLARA_CONFIG_CONSOLE_WIDTH CLARA_CONFIG_CONSOLE_WIDTH #undef CLARA_CONFIG_CONSOLE_WIDTH #endif #define CLARA_CONFIG_CONSOLE_WIDTH CATCH_CONFIG_CONSOLE_WIDTH // Declare Clara inside the Catch namespace #define STITCH_CLARA_OPEN_NAMESPACE namespace Catch { // #included from: ../external/clara.h // Version 0.0.2.4 // Only use header guard if we are not using an outer namespace #if !defined(TWOBLUECUBES_CLARA_H_INCLUDED) || defined(STITCH_CLARA_OPEN_NAMESPACE) #ifndef STITCH_CLARA_OPEN_NAMESPACE #define TWOBLUECUBES_CLARA_H_INCLUDED #define STITCH_CLARA_OPEN_NAMESPACE #define STITCH_CLARA_CLOSE_NAMESPACE #else #define STITCH_CLARA_CLOSE_NAMESPACE } #endif #define STITCH_TBC_TEXT_FORMAT_OPEN_NAMESPACE STITCH_CLARA_OPEN_NAMESPACE // ----------- #included from tbc_text_format.h ----------- // Only use header guard if we are not using an outer namespace #if !defined(TBC_TEXT_FORMAT_H_INCLUDED) || defined(STITCH_TBC_TEXT_FORMAT_OUTER_NAMESPACE) #ifndef STITCH_TBC_TEXT_FORMAT_OUTER_NAMESPACE #define TBC_TEXT_FORMAT_H_INCLUDED #endif #include #include #include #include #include // Use optional outer namespace #ifdef STITCH_TBC_TEXT_FORMAT_OUTER_NAMESPACE namespace STITCH_TBC_TEXT_FORMAT_OUTER_NAMESPACE { #endif namespace Tbc { #ifdef TBC_TEXT_FORMAT_CONSOLE_WIDTH const unsigned int consoleWidth = TBC_TEXT_FORMAT_CONSOLE_WIDTH; #else const unsigned int consoleWidth = 80; #endif struct TextAttributes { TextAttributes() : initialIndent( std::string::npos ), indent( 0 ), width( consoleWidth-1 ), tabChar( '\t' ) {} TextAttributes& setInitialIndent( std::size_t _value ) { initialIndent = _value; return *this; } TextAttributes& setIndent( std::size_t _value ) { indent = _value; return *this; } TextAttributes& setWidth( std::size_t _value ) { width = _value; return *this; } TextAttributes& setTabChar( char _value ) { tabChar = _value; return *this; } std::size_t initialIndent; // indent of first line, or npos std::size_t indent; // indent of subsequent lines, or all if initialIndent is npos std::size_t width; // maximum width of text, including indent. Longer text will wrap char tabChar; // If this char is seen the indent is changed to current pos }; class Text { public: Text( std::string const& _str, TextAttributes const& _attr = TextAttributes() ) : attr( _attr ) { std::string wrappableChars = " [({.,/|\\-"; std::size_t indent = _attr.initialIndent != std::string::npos ? _attr.initialIndent : _attr.indent; std::string remainder = _str; while( !remainder.empty() ) { if( lines.size() >= 1000 ) { lines.push_back( "... message truncated due to excessive size" ); return; } std::size_t tabPos = std::string::npos; std::size_t width = (std::min)( remainder.size(), _attr.width - indent ); std::size_t pos = remainder.find_first_of( '\n' ); if( pos <= width ) { width = pos; } pos = remainder.find_last_of( _attr.tabChar, width ); if( pos != std::string::npos ) { tabPos = pos; if( remainder[width] == '\n' ) width--; remainder = remainder.substr( 0, tabPos ) + remainder.substr( tabPos+1 ); } if( width == remainder.size() ) { spliceLine( indent, remainder, width ); } else if( remainder[width] == '\n' ) { spliceLine( indent, remainder, width ); if( width <= 1 || remainder.size() != 1 ) remainder = remainder.substr( 1 ); indent = _attr.indent; } else { pos = remainder.find_last_of( wrappableChars, width ); if( pos != std::string::npos && pos > 0 ) { spliceLine( indent, remainder, pos ); if( remainder[0] == ' ' ) remainder = remainder.substr( 1 ); } else { spliceLine( indent, remainder, width-1 ); lines.back() += "-"; } if( lines.size() == 1 ) indent = _attr.indent; if( tabPos != std::string::npos ) indent += tabPos; } } } void spliceLine( std::size_t _indent, std::string& _remainder, std::size_t _pos ) { lines.push_back( std::string( _indent, ' ' ) + _remainder.substr( 0, _pos ) ); _remainder = _remainder.substr( _pos ); } typedef std::vector::const_iterator const_iterator; const_iterator begin() const { return lines.begin(); } const_iterator end() const { return lines.end(); } std::string const& last() const { return lines.back(); } std::size_t size() const { return lines.size(); } std::string const& operator[]( std::size_t _index ) const { return lines[_index]; } std::string toString() const { std::ostringstream oss; oss << *this; return oss.str(); } friend std::ostream& operator << ( std::ostream& _stream, Text const& _text ) { for( Text::const_iterator it = _text.begin(), itEnd = _text.end(); it != itEnd; ++it ) { if( it != _text.begin() ) _stream << "\n"; _stream << *it; } return _stream; } private: std::string str; TextAttributes attr; std::vector lines; }; } // end namespace Tbc #ifdef STITCH_TBC_TEXT_FORMAT_OUTER_NAMESPACE } // end outer namespace #endif #endif // TBC_TEXT_FORMAT_H_INCLUDED // ----------- end of #include from tbc_text_format.h ----------- // ........... back in clara.h #undef STITCH_TBC_TEXT_FORMAT_OPEN_NAMESPACE // ----------- #included from clara_compilers.h ----------- #ifndef TWOBLUECUBES_CLARA_COMPILERS_H_INCLUDED #define TWOBLUECUBES_CLARA_COMPILERS_H_INCLUDED // Detect a number of compiler features - mostly C++11/14 conformance - by compiler // The following features are defined: // // CLARA_CONFIG_CPP11_NULLPTR : is nullptr supported? // CLARA_CONFIG_CPP11_NOEXCEPT : is noexcept supported? // CLARA_CONFIG_CPP11_GENERATED_METHODS : The delete and default keywords for compiler generated methods // CLARA_CONFIG_CPP11_OVERRIDE : is override supported? // CLARA_CONFIG_CPP11_UNIQUE_PTR : is unique_ptr supported (otherwise use auto_ptr) // CLARA_CONFIG_CPP11_OR_GREATER : Is C++11 supported? // CLARA_CONFIG_VARIADIC_MACROS : are variadic macros supported? // In general each macro has a _NO_ form // (e.g. CLARA_CONFIG_CPP11_NO_NULLPTR) which disables the feature. // Many features, at point of detection, define an _INTERNAL_ macro, so they // can be combined, en-mass, with the _NO_ forms later. // All the C++11 features can be disabled with CLARA_CONFIG_NO_CPP11 #ifdef __clang__ #if __has_feature(cxx_nullptr) #define CLARA_INTERNAL_CONFIG_CPP11_NULLPTR #endif #if __has_feature(cxx_noexcept) #define CLARA_INTERNAL_CONFIG_CPP11_NOEXCEPT #endif #endif // __clang__ //////////////////////////////////////////////////////////////////////////////// // GCC #ifdef __GNUC__ #if __GNUC__ == 4 && __GNUC_MINOR__ >= 6 && defined(__GXX_EXPERIMENTAL_CXX0X__) #define CLARA_INTERNAL_CONFIG_CPP11_NULLPTR #endif // - otherwise more recent versions define __cplusplus >= 201103L // and will get picked up below #endif // __GNUC__ //////////////////////////////////////////////////////////////////////////////// // Visual C++ #ifdef _MSC_VER #if (_MSC_VER >= 1600) #define CLARA_INTERNAL_CONFIG_CPP11_NULLPTR #define CLARA_INTERNAL_CONFIG_CPP11_UNIQUE_PTR #endif #if (_MSC_VER >= 1900 ) // (VC++ 13 (VS2015)) #define CLARA_INTERNAL_CONFIG_CPP11_NOEXCEPT #define CLARA_INTERNAL_CONFIG_CPP11_GENERATED_METHODS #endif #endif // _MSC_VER //////////////////////////////////////////////////////////////////////////////// // C++ language feature support // catch all support for C++11 #if defined(__cplusplus) && __cplusplus >= 201103L #define CLARA_CPP11_OR_GREATER #if !defined(CLARA_INTERNAL_CONFIG_CPP11_NULLPTR) #define CLARA_INTERNAL_CONFIG_CPP11_NULLPTR #endif #ifndef CLARA_INTERNAL_CONFIG_CPP11_NOEXCEPT #define CLARA_INTERNAL_CONFIG_CPP11_NOEXCEPT #endif #ifndef CLARA_INTERNAL_CONFIG_CPP11_GENERATED_METHODS #define CLARA_INTERNAL_CONFIG_CPP11_GENERATED_METHODS #endif #if !defined(CLARA_INTERNAL_CONFIG_CPP11_OVERRIDE) #define CLARA_INTERNAL_CONFIG_CPP11_OVERRIDE #endif #if !defined(CLARA_INTERNAL_CONFIG_CPP11_UNIQUE_PTR) #define CLARA_INTERNAL_CONFIG_CPP11_UNIQUE_PTR #endif #endif // __cplusplus >= 201103L // Now set the actual defines based on the above + anything the user has configured #if defined(CLARA_INTERNAL_CONFIG_CPP11_NULLPTR) && !defined(CLARA_CONFIG_CPP11_NO_NULLPTR) && !defined(CLARA_CONFIG_CPP11_NULLPTR) && !defined(CLARA_CONFIG_NO_CPP11) #define CLARA_CONFIG_CPP11_NULLPTR #endif #if defined(CLARA_INTERNAL_CONFIG_CPP11_NOEXCEPT) && !defined(CLARA_CONFIG_CPP11_NO_NOEXCEPT) && !defined(CLARA_CONFIG_CPP11_NOEXCEPT) && !defined(CLARA_CONFIG_NO_CPP11) #define CLARA_CONFIG_CPP11_NOEXCEPT #endif #if defined(CLARA_INTERNAL_CONFIG_CPP11_GENERATED_METHODS) && !defined(CLARA_CONFIG_CPP11_NO_GENERATED_METHODS) && !defined(CLARA_CONFIG_CPP11_GENERATED_METHODS) && !defined(CLARA_CONFIG_NO_CPP11) #define CLARA_CONFIG_CPP11_GENERATED_METHODS #endif #if defined(CLARA_INTERNAL_CONFIG_CPP11_OVERRIDE) && !defined(CLARA_CONFIG_NO_OVERRIDE) && !defined(CLARA_CONFIG_CPP11_OVERRIDE) && !defined(CLARA_CONFIG_NO_CPP11) #define CLARA_CONFIG_CPP11_OVERRIDE #endif #if defined(CLARA_INTERNAL_CONFIG_CPP11_UNIQUE_PTR) && !defined(CLARA_CONFIG_NO_UNIQUE_PTR) && !defined(CLARA_CONFIG_CPP11_UNIQUE_PTR) && !defined(CLARA_CONFIG_NO_CPP11) #define CLARA_CONFIG_CPP11_UNIQUE_PTR #endif // noexcept support: #if defined(CLARA_CONFIG_CPP11_NOEXCEPT) && !defined(CLARA_NOEXCEPT) #define CLARA_NOEXCEPT noexcept # define CLARA_NOEXCEPT_IS(x) noexcept(x) #else #define CLARA_NOEXCEPT throw() # define CLARA_NOEXCEPT_IS(x) #endif // nullptr support #ifdef CLARA_CONFIG_CPP11_NULLPTR #define CLARA_NULL nullptr #else #define CLARA_NULL NULL #endif // override support #ifdef CLARA_CONFIG_CPP11_OVERRIDE #define CLARA_OVERRIDE override #else #define CLARA_OVERRIDE #endif // unique_ptr support #ifdef CLARA_CONFIG_CPP11_UNIQUE_PTR # define CLARA_AUTO_PTR( T ) std::unique_ptr #else # define CLARA_AUTO_PTR( T ) std::auto_ptr #endif #endif // TWOBLUECUBES_CLARA_COMPILERS_H_INCLUDED // ----------- end of #include from clara_compilers.h ----------- // ........... back in clara.h #include #include #include #if defined(WIN32) || defined(__WIN32__) || defined(_WIN32) || defined(_MSC_VER) #define CLARA_PLATFORM_WINDOWS #endif // Use optional outer namespace #ifdef STITCH_CLARA_OPEN_NAMESPACE STITCH_CLARA_OPEN_NAMESPACE #endif namespace Clara { struct UnpositionalTag {}; extern UnpositionalTag _; #ifdef CLARA_CONFIG_MAIN UnpositionalTag _; #endif namespace Detail { #ifdef CLARA_CONSOLE_WIDTH const unsigned int consoleWidth = CLARA_CONFIG_CONSOLE_WIDTH; #else const unsigned int consoleWidth = 80; #endif using namespace Tbc; inline bool startsWith( std::string const& str, std::string const& prefix ) { return str.size() >= prefix.size() && str.substr( 0, prefix.size() ) == prefix; } template struct RemoveConstRef{ typedef T type; }; template struct RemoveConstRef{ typedef T type; }; template struct RemoveConstRef{ typedef T type; }; template struct RemoveConstRef{ typedef T type; }; template struct IsBool { static const bool value = false; }; template<> struct IsBool { static const bool value = true; }; template void convertInto( std::string const& _source, T& _dest ) { std::stringstream ss; ss << _source; ss >> _dest; if( ss.fail() ) throw std::runtime_error( "Unable to convert " + _source + " to destination type" ); } inline void convertInto( std::string const& _source, std::string& _dest ) { _dest = _source; } char toLowerCh(char c) { return static_cast( std::tolower( c ) ); } inline void convertInto( std::string const& _source, bool& _dest ) { std::string sourceLC = _source; std::transform( sourceLC.begin(), sourceLC.end(), sourceLC.begin(), toLowerCh ); if( sourceLC == "y" || sourceLC == "1" || sourceLC == "true" || sourceLC == "yes" || sourceLC == "on" ) _dest = true; else if( sourceLC == "n" || sourceLC == "0" || sourceLC == "false" || sourceLC == "no" || sourceLC == "off" ) _dest = false; else throw std::runtime_error( "Expected a boolean value but did not recognise:\n '" + _source + "'" ); } template struct IArgFunction { virtual ~IArgFunction() {} #ifdef CLARA_CONFIG_CPP11_GENERATED_METHODS IArgFunction() = default; IArgFunction( IArgFunction const& ) = default; #endif virtual void set( ConfigT& config, std::string const& value ) const = 0; virtual bool takesArg() const = 0; virtual IArgFunction* clone() const = 0; }; template class BoundArgFunction { public: BoundArgFunction() : functionObj( CLARA_NULL ) {} BoundArgFunction( IArgFunction* _functionObj ) : functionObj( _functionObj ) {} BoundArgFunction( BoundArgFunction const& other ) : functionObj( other.functionObj ? other.functionObj->clone() : CLARA_NULL ) {} BoundArgFunction& operator = ( BoundArgFunction const& other ) { IArgFunction* newFunctionObj = other.functionObj ? other.functionObj->clone() : CLARA_NULL; delete functionObj; functionObj = newFunctionObj; return *this; } ~BoundArgFunction() { delete functionObj; } void set( ConfigT& config, std::string const& value ) const { functionObj->set( config, value ); } bool takesArg() const { return functionObj->takesArg(); } bool isSet() const { return functionObj != CLARA_NULL; } private: IArgFunction* functionObj; }; template struct NullBinder : IArgFunction{ virtual void set( C&, std::string const& ) const {} virtual bool takesArg() const { return true; } virtual IArgFunction* clone() const { return new NullBinder( *this ); } }; template struct BoundDataMember : IArgFunction{ BoundDataMember( M C::* _member ) : member( _member ) {} virtual void set( C& p, std::string const& stringValue ) const { convertInto( stringValue, p.*member ); } virtual bool takesArg() const { return !IsBool::value; } virtual IArgFunction* clone() const { return new BoundDataMember( *this ); } M C::* member; }; template struct BoundUnaryMethod : IArgFunction{ BoundUnaryMethod( void (C::*_member)( M ) ) : member( _member ) {} virtual void set( C& p, std::string const& stringValue ) const { typename RemoveConstRef::type value; convertInto( stringValue, value ); (p.*member)( value ); } virtual bool takesArg() const { return !IsBool::value; } virtual IArgFunction* clone() const { return new BoundUnaryMethod( *this ); } void (C::*member)( M ); }; template struct BoundNullaryMethod : IArgFunction{ BoundNullaryMethod( void (C::*_member)() ) : member( _member ) {} virtual void set( C& p, std::string const& stringValue ) const { bool value; convertInto( stringValue, value ); if( value ) (p.*member)(); } virtual bool takesArg() const { return false; } virtual IArgFunction* clone() const { return new BoundNullaryMethod( *this ); } void (C::*member)(); }; template struct BoundUnaryFunction : IArgFunction{ BoundUnaryFunction( void (*_function)( C& ) ) : function( _function ) {} virtual void set( C& obj, std::string const& stringValue ) const { bool value; convertInto( stringValue, value ); if( value ) function( obj ); } virtual bool takesArg() const { return false; } virtual IArgFunction* clone() const { return new BoundUnaryFunction( *this ); } void (*function)( C& ); }; template struct BoundBinaryFunction : IArgFunction{ BoundBinaryFunction( void (*_function)( C&, T ) ) : function( _function ) {} virtual void set( C& obj, std::string const& stringValue ) const { typename RemoveConstRef::type value; convertInto( stringValue, value ); function( obj, value ); } virtual bool takesArg() const { return !IsBool::value; } virtual IArgFunction* clone() const { return new BoundBinaryFunction( *this ); } void (*function)( C&, T ); }; } // namespace Detail inline std::vector argsToVector( int argc, char const* const* const argv ) { std::vector args( static_cast( argc ) ); for( std::size_t i = 0; i < static_cast( argc ); ++i ) args[i] = argv[i]; return args; } class Parser { enum Mode { None, MaybeShortOpt, SlashOpt, ShortOpt, LongOpt, Positional }; Mode mode; std::size_t from; bool inQuotes; public: struct Token { enum Type { Positional, ShortOpt, LongOpt }; Token( Type _type, std::string const& _data ) : type( _type ), data( _data ) {} Type type; std::string data; }; Parser() : mode( None ), from( 0 ), inQuotes( false ){} void parseIntoTokens( std::vector const& args, std::vector& tokens ) { const std::string doubleDash = "--"; for( std::size_t i = 1; i < args.size() && args[i] != doubleDash; ++i ) parseIntoTokens( args[i], tokens); } void parseIntoTokens( std::string const& arg, std::vector& tokens ) { for( std::size_t i = 0; i < arg.size(); ++i ) { char c = arg[i]; if( c == '"' ) inQuotes = !inQuotes; mode = handleMode( i, c, arg, tokens ); } mode = handleMode( arg.size(), '\0', arg, tokens ); } Mode handleMode( std::size_t i, char c, std::string const& arg, std::vector& tokens ) { switch( mode ) { case None: return handleNone( i, c ); case MaybeShortOpt: return handleMaybeShortOpt( i, c ); case ShortOpt: case LongOpt: case SlashOpt: return handleOpt( i, c, arg, tokens ); case Positional: return handlePositional( i, c, arg, tokens ); default: throw std::logic_error( "Unknown mode" ); } } Mode handleNone( std::size_t i, char c ) { if( inQuotes ) { from = i; return Positional; } switch( c ) { case '-': return MaybeShortOpt; #ifdef CLARA_PLATFORM_WINDOWS case '/': from = i+1; return SlashOpt; #endif default: from = i; return Positional; } } Mode handleMaybeShortOpt( std::size_t i, char c ) { switch( c ) { case '-': from = i+1; return LongOpt; default: from = i; return ShortOpt; } } Mode handleOpt( std::size_t i, char c, std::string const& arg, std::vector& tokens ) { if( std::string( ":=\0", 3 ).find( c ) == std::string::npos ) return mode; std::string optName = arg.substr( from, i-from ); if( mode == ShortOpt ) for( std::size_t j = 0; j < optName.size(); ++j ) tokens.push_back( Token( Token::ShortOpt, optName.substr( j, 1 ) ) ); else if( mode == SlashOpt && optName.size() == 1 ) tokens.push_back( Token( Token::ShortOpt, optName ) ); else tokens.push_back( Token( Token::LongOpt, optName ) ); return None; } Mode handlePositional( std::size_t i, char c, std::string const& arg, std::vector& tokens ) { if( inQuotes || std::string( "\0", 1 ).find( c ) == std::string::npos ) return mode; std::string data = arg.substr( from, i-from ); tokens.push_back( Token( Token::Positional, data ) ); return None; } }; template struct CommonArgProperties { CommonArgProperties() {} CommonArgProperties( Detail::BoundArgFunction const& _boundField ) : boundField( _boundField ) {} Detail::BoundArgFunction boundField; std::string description; std::string detail; std::string placeholder; // Only value if boundField takes an arg bool takesArg() const { return !placeholder.empty(); } void validate() const { if( !boundField.isSet() ) throw std::logic_error( "option not bound" ); } }; struct OptionArgProperties { std::vector shortNames; std::string longName; bool hasShortName( std::string const& shortName ) const { return std::find( shortNames.begin(), shortNames.end(), shortName ) != shortNames.end(); } bool hasLongName( std::string const& _longName ) const { return _longName == longName; } }; struct PositionalArgProperties { PositionalArgProperties() : position( -1 ) {} int position; // -1 means non-positional (floating) bool isFixedPositional() const { return position != -1; } }; template class CommandLine { struct Arg : CommonArgProperties, OptionArgProperties, PositionalArgProperties { Arg() {} Arg( Detail::BoundArgFunction const& _boundField ) : CommonArgProperties( _boundField ) {} using CommonArgProperties::placeholder; // !TBD std::string dbgName() const { if( !longName.empty() ) return "--" + longName; if( !shortNames.empty() ) return "-" + shortNames[0]; return "positional args"; } std::string commands() const { std::ostringstream oss; bool first = true; std::vector::const_iterator it = shortNames.begin(), itEnd = shortNames.end(); for(; it != itEnd; ++it ) { if( first ) first = false; else oss << ", "; oss << "-" << *it; } if( !longName.empty() ) { if( !first ) oss << ", "; oss << "--" << longName; } if( !placeholder.empty() ) oss << " <" << placeholder << ">"; return oss.str(); } }; typedef CLARA_AUTO_PTR( Arg ) ArgAutoPtr; friend void addOptName( Arg& arg, std::string const& optName ) { if( optName.empty() ) return; if( Detail::startsWith( optName, "--" ) ) { if( !arg.longName.empty() ) throw std::logic_error( "Only one long opt may be specified. '" + arg.longName + "' already specified, now attempting to add '" + optName + "'" ); arg.longName = optName.substr( 2 ); } else if( Detail::startsWith( optName, "-" ) ) arg.shortNames.push_back( optName.substr( 1 ) ); else throw std::logic_error( "option must begin with - or --. Option was: '" + optName + "'" ); } friend void setPositionalArg( Arg& arg, int position ) { arg.position = position; } class ArgBuilder { public: ArgBuilder( Arg* arg ) : m_arg( arg ) {} // Bind a non-boolean data member (requires placeholder string) template void bind( M C::* field, std::string const& placeholder ) { m_arg->boundField = new Detail::BoundDataMember( field ); m_arg->placeholder = placeholder; } // Bind a boolean data member (no placeholder required) template void bind( bool C::* field ) { m_arg->boundField = new Detail::BoundDataMember( field ); } // Bind a method taking a single, non-boolean argument (requires a placeholder string) template void bind( void (C::* unaryMethod)( M ), std::string const& placeholder ) { m_arg->boundField = new Detail::BoundUnaryMethod( unaryMethod ); m_arg->placeholder = placeholder; } // Bind a method taking a single, boolean argument (no placeholder string required) template void bind( void (C::* unaryMethod)( bool ) ) { m_arg->boundField = new Detail::BoundUnaryMethod( unaryMethod ); } // Bind a method that takes no arguments (will be called if opt is present) template void bind( void (C::* nullaryMethod)() ) { m_arg->boundField = new Detail::BoundNullaryMethod( nullaryMethod ); } // Bind a free function taking a single argument - the object to operate on (no placeholder string required) template void bind( void (* unaryFunction)( C& ) ) { m_arg->boundField = new Detail::BoundUnaryFunction( unaryFunction ); } // Bind a free function taking a single argument - the object to operate on (requires a placeholder string) template void bind( void (* binaryFunction)( C&, T ), std::string const& placeholder ) { m_arg->boundField = new Detail::BoundBinaryFunction( binaryFunction ); m_arg->placeholder = placeholder; } ArgBuilder& describe( std::string const& description ) { m_arg->description = description; return *this; } ArgBuilder& detail( std::string const& detail ) { m_arg->detail = detail; return *this; } protected: Arg* m_arg; }; class OptBuilder : public ArgBuilder { public: OptBuilder( Arg* arg ) : ArgBuilder( arg ) {} OptBuilder( OptBuilder& other ) : ArgBuilder( other ) {} OptBuilder& operator[]( std::string const& optName ) { addOptName( *ArgBuilder::m_arg, optName ); return *this; } }; public: CommandLine() : m_boundProcessName( new Detail::NullBinder() ), m_highestSpecifiedArgPosition( 0 ), m_throwOnUnrecognisedTokens( false ) {} CommandLine( CommandLine const& other ) : m_boundProcessName( other.m_boundProcessName ), m_options ( other.m_options ), m_positionalArgs( other.m_positionalArgs ), m_highestSpecifiedArgPosition( other.m_highestSpecifiedArgPosition ), m_throwOnUnrecognisedTokens( other.m_throwOnUnrecognisedTokens ) { if( other.m_floatingArg.get() ) m_floatingArg.reset( new Arg( *other.m_floatingArg ) ); } CommandLine& setThrowOnUnrecognisedTokens( bool shouldThrow = true ) { m_throwOnUnrecognisedTokens = shouldThrow; return *this; } OptBuilder operator[]( std::string const& optName ) { m_options.push_back( Arg() ); addOptName( m_options.back(), optName ); OptBuilder builder( &m_options.back() ); return builder; } ArgBuilder operator[]( int position ) { m_positionalArgs.insert( std::make_pair( position, Arg() ) ); if( position > m_highestSpecifiedArgPosition ) m_highestSpecifiedArgPosition = position; setPositionalArg( m_positionalArgs[position], position ); ArgBuilder builder( &m_positionalArgs[position] ); return builder; } // Invoke this with the _ instance ArgBuilder operator[]( UnpositionalTag ) { if( m_floatingArg.get() ) throw std::logic_error( "Only one unpositional argument can be added" ); m_floatingArg.reset( new Arg() ); ArgBuilder builder( m_floatingArg.get() ); return builder; } template void bindProcessName( M C::* field ) { m_boundProcessName = new Detail::BoundDataMember( field ); } template void bindProcessName( void (C::*_unaryMethod)( M ) ) { m_boundProcessName = new Detail::BoundUnaryMethod( _unaryMethod ); } void optUsage( std::ostream& os, std::size_t indent = 0, std::size_t width = Detail::consoleWidth ) const { typename std::vector::const_iterator itBegin = m_options.begin(), itEnd = m_options.end(), it; std::size_t maxWidth = 0; for( it = itBegin; it != itEnd; ++it ) maxWidth = (std::max)( maxWidth, it->commands().size() ); for( it = itBegin; it != itEnd; ++it ) { Detail::Text usage( it->commands(), Detail::TextAttributes() .setWidth( maxWidth+indent ) .setIndent( indent ) ); Detail::Text desc( it->description, Detail::TextAttributes() .setWidth( width - maxWidth - 3 ) ); for( std::size_t i = 0; i < (std::max)( usage.size(), desc.size() ); ++i ) { std::string usageCol = i < usage.size() ? usage[i] : ""; os << usageCol; if( i < desc.size() && !desc[i].empty() ) os << std::string( indent + 2 + maxWidth - usageCol.size(), ' ' ) << desc[i]; os << "\n"; } } } std::string optUsage() const { std::ostringstream oss; optUsage( oss ); return oss.str(); } void argSynopsis( std::ostream& os ) const { for( int i = 1; i <= m_highestSpecifiedArgPosition; ++i ) { if( i > 1 ) os << " "; typename std::map::const_iterator it = m_positionalArgs.find( i ); if( it != m_positionalArgs.end() ) os << "<" << it->second.placeholder << ">"; else if( m_floatingArg.get() ) os << "<" << m_floatingArg->placeholder << ">"; else throw std::logic_error( "non consecutive positional arguments with no floating args" ); } // !TBD No indication of mandatory args if( m_floatingArg.get() ) { if( m_highestSpecifiedArgPosition > 1 ) os << " "; os << "[<" << m_floatingArg->placeholder << "> ...]"; } } std::string argSynopsis() const { std::ostringstream oss; argSynopsis( oss ); return oss.str(); } void usage( std::ostream& os, std::string const& procName ) const { validate(); os << "usage:\n " << procName << " "; argSynopsis( os ); if( !m_options.empty() ) { os << " [options]\n\nwhere options are: \n"; optUsage( os, 2 ); } os << "\n"; } std::string usage( std::string const& procName ) const { std::ostringstream oss; usage( oss, procName ); return oss.str(); } ConfigT parse( std::vector const& args ) const { ConfigT config; parseInto( args, config ); return config; } std::vector parseInto( std::vector const& args, ConfigT& config ) const { std::string processName = args.empty() ? std::string() : args[0]; std::size_t lastSlash = processName.find_last_of( "/\\" ); if( lastSlash != std::string::npos ) processName = processName.substr( lastSlash+1 ); m_boundProcessName.set( config, processName ); std::vector tokens; Parser parser; parser.parseIntoTokens( args, tokens ); return populate( tokens, config ); } std::vector populate( std::vector const& tokens, ConfigT& config ) const { validate(); std::vector unusedTokens = populateOptions( tokens, config ); unusedTokens = populateFixedArgs( unusedTokens, config ); unusedTokens = populateFloatingArgs( unusedTokens, config ); return unusedTokens; } std::vector populateOptions( std::vector const& tokens, ConfigT& config ) const { std::vector unusedTokens; std::vector errors; for( std::size_t i = 0; i < tokens.size(); ++i ) { Parser::Token const& token = tokens[i]; typename std::vector::const_iterator it = m_options.begin(), itEnd = m_options.end(); for(; it != itEnd; ++it ) { Arg const& arg = *it; try { if( ( token.type == Parser::Token::ShortOpt && arg.hasShortName( token.data ) ) || ( token.type == Parser::Token::LongOpt && arg.hasLongName( token.data ) ) ) { if( arg.takesArg() ) { if( i == tokens.size()-1 || tokens[i+1].type != Parser::Token::Positional ) errors.push_back( "Expected argument to option: " + token.data ); else arg.boundField.set( config, tokens[++i].data ); } else { arg.boundField.set( config, "true" ); } break; } } catch( std::exception& ex ) { errors.push_back( std::string( ex.what() ) + "\n- while parsing: (" + arg.commands() + ")" ); } } if( it == itEnd ) { if( token.type == Parser::Token::Positional || !m_throwOnUnrecognisedTokens ) unusedTokens.push_back( token ); else if( errors.empty() && m_throwOnUnrecognisedTokens ) errors.push_back( "unrecognised option: " + token.data ); } } if( !errors.empty() ) { std::ostringstream oss; for( std::vector::const_iterator it = errors.begin(), itEnd = errors.end(); it != itEnd; ++it ) { if( it != errors.begin() ) oss << "\n"; oss << *it; } throw std::runtime_error( oss.str() ); } return unusedTokens; } std::vector populateFixedArgs( std::vector const& tokens, ConfigT& config ) const { std::vector unusedTokens; int position = 1; for( std::size_t i = 0; i < tokens.size(); ++i ) { Parser::Token const& token = tokens[i]; typename std::map::const_iterator it = m_positionalArgs.find( position ); if( it != m_positionalArgs.end() ) it->second.boundField.set( config, token.data ); else unusedTokens.push_back( token ); if( token.type == Parser::Token::Positional ) position++; } return unusedTokens; } std::vector populateFloatingArgs( std::vector const& tokens, ConfigT& config ) const { if( !m_floatingArg.get() ) return tokens; std::vector unusedTokens; for( std::size_t i = 0; i < tokens.size(); ++i ) { Parser::Token const& token = tokens[i]; if( token.type == Parser::Token::Positional ) m_floatingArg->boundField.set( config, token.data ); else unusedTokens.push_back( token ); } return unusedTokens; } void validate() const { if( m_options.empty() && m_positionalArgs.empty() && !m_floatingArg.get() ) throw std::logic_error( "No options or arguments specified" ); for( typename std::vector::const_iterator it = m_options.begin(), itEnd = m_options.end(); it != itEnd; ++it ) it->validate(); } private: Detail::BoundArgFunction m_boundProcessName; std::vector m_options; std::map m_positionalArgs; ArgAutoPtr m_floatingArg; int m_highestSpecifiedArgPosition; bool m_throwOnUnrecognisedTokens; }; } // end namespace Clara STITCH_CLARA_CLOSE_NAMESPACE #undef STITCH_CLARA_OPEN_NAMESPACE #undef STITCH_CLARA_CLOSE_NAMESPACE #endif // TWOBLUECUBES_CLARA_H_INCLUDED #undef STITCH_CLARA_OPEN_NAMESPACE // Restore Clara's value for console width, if present #ifdef CATCH_TEMP_CLARA_CONFIG_CONSOLE_WIDTH #define CLARA_CONFIG_CONSOLE_WIDTH CATCH_TEMP_CLARA_CONFIG_CONSOLE_WIDTH #undef CATCH_TEMP_CLARA_CONFIG_CONSOLE_WIDTH #endif #include #include namespace Catch { inline void abortAfterFirst( ConfigData& config ) { config.abortAfter = 1; } inline void abortAfterX( ConfigData& config, int x ) { if( x < 1 ) throw std::runtime_error( "Value after -x or --abortAfter must be greater than zero" ); config.abortAfter = x; } inline void addTestOrTags( ConfigData& config, std::string const& _testSpec ) { config.testsOrTags.push_back( _testSpec ); } inline void addSectionToRun( ConfigData& config, std::string const& sectionName ) { config.sectionsToRun.push_back( sectionName ); } inline void addReporterName( ConfigData& config, std::string const& _reporterName ) { config.reporterNames.push_back( _reporterName ); } inline void addWarning( ConfigData& config, std::string const& _warning ) { if( _warning == "NoAssertions" ) config.warnings = static_cast( config.warnings | WarnAbout::NoAssertions ); else throw std::runtime_error( "Unrecognised warning: '" + _warning + '\'' ); } inline void setOrder( ConfigData& config, std::string const& order ) { if( startsWith( "declared", order ) ) config.runOrder = RunTests::InDeclarationOrder; else if( startsWith( "lexical", order ) ) config.runOrder = RunTests::InLexicographicalOrder; else if( startsWith( "random", order ) ) config.runOrder = RunTests::InRandomOrder; else throw std::runtime_error( "Unrecognised ordering: '" + order + '\'' ); } inline void setRngSeed( ConfigData& config, std::string const& seed ) { if( seed == "time" ) { config.rngSeed = static_cast( std::time(0) ); } else { std::stringstream ss; ss << seed; ss >> config.rngSeed; if( ss.fail() ) throw std::runtime_error( "Argument to --rng-seed should be the word 'time' or a number" ); } } inline void setVerbosity( ConfigData& config, int level ) { // !TBD: accept strings? config.verbosity = static_cast( level ); } inline void setShowDurations( ConfigData& config, bool _showDurations ) { config.showDurations = _showDurations ? ShowDurations::Always : ShowDurations::Never; } inline void setUseColour( ConfigData& config, std::string const& value ) { std::string mode = toLower( value ); if( mode == "yes" ) config.useColour = UseColour::Yes; else if( mode == "no" ) config.useColour = UseColour::No; else if( mode == "auto" ) config.useColour = UseColour::Auto; else throw std::runtime_error( "colour mode must be one of: auto, yes or no" ); } inline void setWaitForKeypress( ConfigData& config, std::string const& keypress ) { std::string keypressLc = toLower( keypress ); if( keypressLc == "start" ) config.waitForKeypress = WaitForKeypress::BeforeStart; else if( keypressLc == "exit" ) config.waitForKeypress = WaitForKeypress::BeforeExit; else if( keypressLc == "both" ) config.waitForKeypress = WaitForKeypress::BeforeStartAndExit; else throw std::runtime_error( "keypress argument must be one of: start, exit or both. '" + keypress + "' not recognised" ); }; inline void forceColour( ConfigData& config ) { config.useColour = UseColour::Yes; } inline void loadTestNamesFromFile( ConfigData& config, std::string const& _filename ) { std::ifstream f( _filename.c_str() ); if( !f.is_open() ) throw std::domain_error( "Unable to load input file: " + _filename ); std::string line; while( std::getline( f, line ) ) { line = trim(line); if( !line.empty() && !startsWith( line, '#' ) ) { if( !startsWith( line, '"' ) ) line = '"' + line + '"'; addTestOrTags( config, line + ',' ); } } } inline Clara::CommandLine makeCommandLineParser() { using namespace Clara; CommandLine cli; cli.bindProcessName( &ConfigData::processName ); cli["-?"]["-h"]["--help"] .describe( "display usage information" ) .bind( &ConfigData::showHelp ); cli["-l"]["--list-tests"] .describe( "list all/matching test cases" ) .bind( &ConfigData::listTests ); cli["-t"]["--list-tags"] .describe( "list all/matching tags" ) .bind( &ConfigData::listTags ); cli["-s"]["--success"] .describe( "include successful tests in output" ) .bind( &ConfigData::showSuccessfulTests ); cli["-b"]["--break"] .describe( "break into debugger on failure" ) .bind( &ConfigData::shouldDebugBreak ); cli["-e"]["--nothrow"] .describe( "skip exception tests" ) .bind( &ConfigData::noThrow ); cli["-i"]["--invisibles"] .describe( "show invisibles (tabs, newlines)" ) .bind( &ConfigData::showInvisibles ); cli["-o"]["--out"] .describe( "output filename" ) .bind( &ConfigData::outputFilename, "filename" ); cli["-r"]["--reporter"] // .placeholder( "name[:filename]" ) .describe( "reporter to use (defaults to console)" ) .bind( &addReporterName, "name" ); cli["-n"]["--name"] .describe( "suite name" ) .bind( &ConfigData::name, "name" ); cli["-a"]["--abort"] .describe( "abort at first failure" ) .bind( &abortAfterFirst ); cli["-x"]["--abortx"] .describe( "abort after x failures" ) .bind( &abortAfterX, "no. failures" ); cli["-w"]["--warn"] .describe( "enable warnings" ) .bind( &addWarning, "warning name" ); // - needs updating if reinstated // cli.into( &setVerbosity ) // .describe( "level of verbosity (0=no output)" ) // .shortOpt( "v") // .longOpt( "verbosity" ) // .placeholder( "level" ); cli[_] .describe( "which test or tests to use" ) .bind( &addTestOrTags, "test name, pattern or tags" ); cli["-d"]["--durations"] .describe( "show test durations" ) .bind( &setShowDurations, "yes|no" ); cli["-f"]["--input-file"] .describe( "load test names to run from a file" ) .bind( &loadTestNamesFromFile, "filename" ); cli["-#"]["--filenames-as-tags"] .describe( "adds a tag for the filename" ) .bind( &ConfigData::filenamesAsTags ); cli["-c"]["--section"] .describe( "specify section to run" ) .bind( &addSectionToRun, "section name" ); // Less common commands which don't have a short form cli["--list-test-names-only"] .describe( "list all/matching test cases names only" ) .bind( &ConfigData::listTestNamesOnly ); cli["--list-extra-info"] .describe( "list all/matching test cases with more info" ) .bind( &ConfigData::listExtraInfo ); cli["--list-reporters"] .describe( "list all reporters" ) .bind( &ConfigData::listReporters ); cli["--order"] .describe( "test case order (defaults to decl)" ) .bind( &setOrder, "decl|lex|rand" ); cli["--rng-seed"] .describe( "set a specific seed for random numbers" ) .bind( &setRngSeed, "'time'|number" ); cli["--force-colour"] .describe( "force colourised output (deprecated)" ) .bind( &forceColour ); cli["--use-colour"] .describe( "should output be colourised" ) .bind( &setUseColour, "yes|no" ); cli["--libidentify"] .describe( "report name and version according to libidentify standard" ) .bind( &ConfigData::libIdentify ); cli["--wait-for-keypress"] .describe( "waits for a keypress before exiting" ) .bind( &setWaitForKeypress, "start|exit|both" ); return cli; } } // end namespace Catch // #included from: internal/catch_list.hpp #define TWOBLUECUBES_CATCH_LIST_HPP_INCLUDED // #included from: catch_text.h #define TWOBLUECUBES_CATCH_TEXT_H_INCLUDED #define TBC_TEXT_FORMAT_CONSOLE_WIDTH CATCH_CONFIG_CONSOLE_WIDTH #define CLICHE_TBC_TEXT_FORMAT_OUTER_NAMESPACE Catch // #included from: ../external/tbc_text_format.h // Only use header guard if we are not using an outer namespace #ifndef CLICHE_TBC_TEXT_FORMAT_OUTER_NAMESPACE # ifdef TWOBLUECUBES_TEXT_FORMAT_H_INCLUDED # ifndef TWOBLUECUBES_TEXT_FORMAT_H_ALREADY_INCLUDED # define TWOBLUECUBES_TEXT_FORMAT_H_ALREADY_INCLUDED # endif # else # define TWOBLUECUBES_TEXT_FORMAT_H_INCLUDED # endif #endif #ifndef TWOBLUECUBES_TEXT_FORMAT_H_ALREADY_INCLUDED #include #include #include // Use optional outer namespace #ifdef CLICHE_TBC_TEXT_FORMAT_OUTER_NAMESPACE namespace CLICHE_TBC_TEXT_FORMAT_OUTER_NAMESPACE { #endif namespace Tbc { #ifdef TBC_TEXT_FORMAT_CONSOLE_WIDTH const unsigned int consoleWidth = TBC_TEXT_FORMAT_CONSOLE_WIDTH; #else const unsigned int consoleWidth = 80; #endif struct TextAttributes { TextAttributes() : initialIndent( std::string::npos ), indent( 0 ), width( consoleWidth-1 ) {} TextAttributes& setInitialIndent( std::size_t _value ) { initialIndent = _value; return *this; } TextAttributes& setIndent( std::size_t _value ) { indent = _value; return *this; } TextAttributes& setWidth( std::size_t _value ) { width = _value; return *this; } std::size_t initialIndent; // indent of first line, or npos std::size_t indent; // indent of subsequent lines, or all if initialIndent is npos std::size_t width; // maximum width of text, including indent. Longer text will wrap }; class Text { public: Text( std::string const& _str, TextAttributes const& _attr = TextAttributes() ) : attr( _attr ) { const std::string wrappableBeforeChars = "[({<\t"; const std::string wrappableAfterChars = "])}>-,./|\\"; const std::string wrappableInsteadOfChars = " \n\r"; std::string indent = _attr.initialIndent != std::string::npos ? std::string( _attr.initialIndent, ' ' ) : std::string( _attr.indent, ' ' ); typedef std::string::const_iterator iterator; iterator it = _str.begin(); const iterator strEnd = _str.end(); while( it != strEnd ) { if( lines.size() >= 1000 ) { lines.push_back( "... message truncated due to excessive size" ); return; } std::string suffix; std::size_t width = (std::min)( static_cast( strEnd-it ), _attr.width-static_cast( indent.size() ) ); iterator itEnd = it+width; iterator itNext = _str.end(); iterator itNewLine = std::find( it, itEnd, '\n' ); if( itNewLine != itEnd ) itEnd = itNewLine; if( itEnd != strEnd ) { bool foundWrapPoint = false; iterator findIt = itEnd; do { if( wrappableAfterChars.find( *findIt ) != std::string::npos && findIt != itEnd ) { itEnd = findIt+1; itNext = findIt+1; foundWrapPoint = true; } else if( findIt > it && wrappableBeforeChars.find( *findIt ) != std::string::npos ) { itEnd = findIt; itNext = findIt; foundWrapPoint = true; } else if( wrappableInsteadOfChars.find( *findIt ) != std::string::npos ) { itNext = findIt+1; itEnd = findIt; foundWrapPoint = true; } if( findIt == it ) break; else --findIt; } while( !foundWrapPoint ); if( !foundWrapPoint ) { // No good wrap char, so we'll break mid word and add a hyphen --itEnd; itNext = itEnd; suffix = "-"; } else { while( itEnd > it && wrappableInsteadOfChars.find( *(itEnd-1) ) != std::string::npos ) --itEnd; } } lines.push_back( indent + std::string( it, itEnd ) + suffix ); if( indent.size() != _attr.indent ) indent = std::string( _attr.indent, ' ' ); it = itNext; } } typedef std::vector::const_iterator const_iterator; const_iterator begin() const { return lines.begin(); } const_iterator end() const { return lines.end(); } std::string const& last() const { return lines.back(); } std::size_t size() const { return lines.size(); } std::string const& operator[]( std::size_t _index ) const { return lines[_index]; } std::string toString() const { std::ostringstream oss; oss << *this; return oss.str(); } inline friend std::ostream& operator << ( std::ostream& _stream, Text const& _text ) { for( Text::const_iterator it = _text.begin(), itEnd = _text.end(); it != itEnd; ++it ) { if( it != _text.begin() ) _stream << "\n"; _stream << *it; } return _stream; } private: std::string str; TextAttributes attr; std::vector lines; }; } // end namespace Tbc #ifdef CLICHE_TBC_TEXT_FORMAT_OUTER_NAMESPACE } // end outer namespace #endif #endif // TWOBLUECUBES_TEXT_FORMAT_H_ALREADY_INCLUDED #undef CLICHE_TBC_TEXT_FORMAT_OUTER_NAMESPACE namespace Catch { using Tbc::Text; using Tbc::TextAttributes; } // #included from: catch_console_colour.hpp #define TWOBLUECUBES_CATCH_CONSOLE_COLOUR_HPP_INCLUDED namespace Catch { struct Colour { enum Code { None = 0, White, Red, Green, Blue, Cyan, Yellow, Grey, Bright = 0x10, BrightRed = Bright | Red, BrightGreen = Bright | Green, LightGrey = Bright | Grey, BrightWhite = Bright | White, // By intention FileName = LightGrey, Warning = Yellow, ResultError = BrightRed, ResultSuccess = BrightGreen, ResultExpectedFailure = Warning, Error = BrightRed, Success = Green, OriginalExpression = Cyan, ReconstructedExpression = Yellow, SecondaryText = LightGrey, Headers = White }; // Use constructed object for RAII guard Colour( Code _colourCode ); Colour( Colour const& other ); ~Colour(); // Use static method for one-shot changes static void use( Code _colourCode ); private: bool m_moved; }; inline std::ostream& operator << ( std::ostream& os, Colour const& ) { return os; } } // end namespace Catch // #included from: catch_interfaces_reporter.h #define TWOBLUECUBES_CATCH_INTERFACES_REPORTER_H_INCLUDED #include #include #include namespace Catch { struct ReporterConfig { explicit ReporterConfig( Ptr const& _fullConfig ) : m_stream( &_fullConfig->stream() ), m_fullConfig( _fullConfig ) {} ReporterConfig( Ptr const& _fullConfig, std::ostream& _stream ) : m_stream( &_stream ), m_fullConfig( _fullConfig ) {} std::ostream& stream() const { return *m_stream; } Ptr fullConfig() const { return m_fullConfig; } private: std::ostream* m_stream; Ptr m_fullConfig; }; struct ReporterPreferences { ReporterPreferences() : shouldRedirectStdOut( false ) {} bool shouldRedirectStdOut; }; template struct LazyStat : Option { LazyStat() : used( false ) {} LazyStat& operator=( T const& _value ) { Option::operator=( _value ); used = false; return *this; } void reset() { Option::reset(); used = false; } bool used; }; struct TestRunInfo { TestRunInfo( std::string const& _name ) : name( _name ) {} std::string name; }; struct GroupInfo { GroupInfo( std::string const& _name, std::size_t _groupIndex, std::size_t _groupsCount ) : name( _name ), groupIndex( _groupIndex ), groupsCounts( _groupsCount ) {} std::string name; std::size_t groupIndex; std::size_t groupsCounts; }; struct AssertionStats { AssertionStats( AssertionResult const& _assertionResult, std::vector const& _infoMessages, Totals const& _totals ) : assertionResult( _assertionResult ), infoMessages( _infoMessages ), totals( _totals ) { if( assertionResult.hasMessage() ) { // Copy message into messages list. // !TBD This should have been done earlier, somewhere MessageBuilder builder( assertionResult.getTestMacroName(), assertionResult.getSourceInfo(), assertionResult.getResultType() ); builder << assertionResult.getMessage(); builder.m_info.message = builder.m_stream.str(); infoMessages.push_back( builder.m_info ); } } virtual ~AssertionStats(); # ifdef CATCH_CONFIG_CPP11_GENERATED_METHODS AssertionStats( AssertionStats const& ) = default; AssertionStats( AssertionStats && ) = default; AssertionStats& operator = ( AssertionStats const& ) = default; AssertionStats& operator = ( AssertionStats && ) = default; # endif AssertionResult assertionResult; std::vector infoMessages; Totals totals; }; struct SectionStats { SectionStats( SectionInfo const& _sectionInfo, Counts const& _assertions, double _durationInSeconds, bool _missingAssertions ) : sectionInfo( _sectionInfo ), assertions( _assertions ), durationInSeconds( _durationInSeconds ), missingAssertions( _missingAssertions ) {} virtual ~SectionStats(); # ifdef CATCH_CONFIG_CPP11_GENERATED_METHODS SectionStats( SectionStats const& ) = default; SectionStats( SectionStats && ) = default; SectionStats& operator = ( SectionStats const& ) = default; SectionStats& operator = ( SectionStats && ) = default; # endif SectionInfo sectionInfo; Counts assertions; double durationInSeconds; bool missingAssertions; }; struct TestCaseStats { TestCaseStats( TestCaseInfo const& _testInfo, Totals const& _totals, std::string const& _stdOut, std::string const& _stdErr, bool _aborting ) : testInfo( _testInfo ), totals( _totals ), stdOut( _stdOut ), stdErr( _stdErr ), aborting( _aborting ) {} virtual ~TestCaseStats(); # ifdef CATCH_CONFIG_CPP11_GENERATED_METHODS TestCaseStats( TestCaseStats const& ) = default; TestCaseStats( TestCaseStats && ) = default; TestCaseStats& operator = ( TestCaseStats const& ) = default; TestCaseStats& operator = ( TestCaseStats && ) = default; # endif TestCaseInfo testInfo; Totals totals; std::string stdOut; std::string stdErr; bool aborting; }; struct TestGroupStats { TestGroupStats( GroupInfo const& _groupInfo, Totals const& _totals, bool _aborting ) : groupInfo( _groupInfo ), totals( _totals ), aborting( _aborting ) {} TestGroupStats( GroupInfo const& _groupInfo ) : groupInfo( _groupInfo ), aborting( false ) {} virtual ~TestGroupStats(); # ifdef CATCH_CONFIG_CPP11_GENERATED_METHODS TestGroupStats( TestGroupStats const& ) = default; TestGroupStats( TestGroupStats && ) = default; TestGroupStats& operator = ( TestGroupStats const& ) = default; TestGroupStats& operator = ( TestGroupStats && ) = default; # endif GroupInfo groupInfo; Totals totals; bool aborting; }; struct TestRunStats { TestRunStats( TestRunInfo const& _runInfo, Totals const& _totals, bool _aborting ) : runInfo( _runInfo ), totals( _totals ), aborting( _aborting ) {} virtual ~TestRunStats(); # ifndef CATCH_CONFIG_CPP11_GENERATED_METHODS TestRunStats( TestRunStats const& _other ) : runInfo( _other.runInfo ), totals( _other.totals ), aborting( _other.aborting ) {} # else TestRunStats( TestRunStats const& ) = default; TestRunStats( TestRunStats && ) = default; TestRunStats& operator = ( TestRunStats const& ) = default; TestRunStats& operator = ( TestRunStats && ) = default; # endif TestRunInfo runInfo; Totals totals; bool aborting; }; class MultipleReporters; struct IStreamingReporter : IShared { virtual ~IStreamingReporter(); // Implementing class must also provide the following static method: // static std::string getDescription(); virtual ReporterPreferences getPreferences() const = 0; virtual void noMatchingTestCases( std::string const& spec ) = 0; virtual void testRunStarting( TestRunInfo const& testRunInfo ) = 0; virtual void testGroupStarting( GroupInfo const& groupInfo ) = 0; virtual void testCaseStarting( TestCaseInfo const& testInfo ) = 0; virtual void sectionStarting( SectionInfo const& sectionInfo ) = 0; virtual void assertionStarting( AssertionInfo const& assertionInfo ) = 0; // The return value indicates if the messages buffer should be cleared: virtual bool assertionEnded( AssertionStats const& assertionStats ) = 0; virtual void sectionEnded( SectionStats const& sectionStats ) = 0; virtual void testCaseEnded( TestCaseStats const& testCaseStats ) = 0; virtual void testGroupEnded( TestGroupStats const& testGroupStats ) = 0; virtual void testRunEnded( TestRunStats const& testRunStats ) = 0; virtual void skipTest( TestCaseInfo const& testInfo ) = 0; virtual MultipleReporters* tryAsMulti() { return CATCH_NULL; } }; struct IReporterFactory : IShared { virtual ~IReporterFactory(); virtual IStreamingReporter* create( ReporterConfig const& config ) const = 0; virtual std::string getDescription() const = 0; }; struct IReporterRegistry { typedef std::map > FactoryMap; typedef std::vector > Listeners; virtual ~IReporterRegistry(); virtual IStreamingReporter* create( std::string const& name, Ptr const& config ) const = 0; virtual FactoryMap const& getFactories() const = 0; virtual Listeners const& getListeners() const = 0; }; Ptr addReporter( Ptr const& existingReporter, Ptr const& additionalReporter ); } #include #include namespace Catch { inline std::size_t listTests( Config const& config ) { TestSpec testSpec = config.testSpec(); if( config.testSpec().hasFilters() ) Catch::cout() << "Matching test cases:\n"; else { Catch::cout() << "All available test cases:\n"; testSpec = TestSpecParser( ITagAliasRegistry::get() ).parse( "*" ).testSpec(); } std::size_t matchedTests = 0; TextAttributes nameAttr, descAttr, tagsAttr; nameAttr.setInitialIndent( 2 ).setIndent( 4 ); descAttr.setIndent( 4 ); tagsAttr.setIndent( 6 ); std::vector matchedTestCases = filterTests( getAllTestCasesSorted( config ), testSpec, config ); for( std::vector::const_iterator it = matchedTestCases.begin(), itEnd = matchedTestCases.end(); it != itEnd; ++it ) { matchedTests++; TestCaseInfo const& testCaseInfo = it->getTestCaseInfo(); Colour::Code colour = testCaseInfo.isHidden() ? Colour::SecondaryText : Colour::None; Colour colourGuard( colour ); Catch::cout() << Text( testCaseInfo.name, nameAttr ) << std::endl; if( config.listExtraInfo() ) { Catch::cout() << " " << testCaseInfo.lineInfo << std::endl; std::string description = testCaseInfo.description; if( description.empty() ) description = "(NO DESCRIPTION)"; Catch::cout() << Text( description, descAttr ) << std::endl; } if( !testCaseInfo.tags.empty() ) Catch::cout() << Text( testCaseInfo.tagsAsString, tagsAttr ) << std::endl; } if( !config.testSpec().hasFilters() ) Catch::cout() << pluralise( matchedTests, "test case" ) << '\n' << std::endl; else Catch::cout() << pluralise( matchedTests, "matching test case" ) << '\n' << std::endl; return matchedTests; } inline std::size_t listTestsNamesOnly( Config const& config ) { TestSpec testSpec = config.testSpec(); if( !config.testSpec().hasFilters() ) testSpec = TestSpecParser( ITagAliasRegistry::get() ).parse( "*" ).testSpec(); std::size_t matchedTests = 0; std::vector matchedTestCases = filterTests( getAllTestCasesSorted( config ), testSpec, config ); for( std::vector::const_iterator it = matchedTestCases.begin(), itEnd = matchedTestCases.end(); it != itEnd; ++it ) { matchedTests++; TestCaseInfo const& testCaseInfo = it->getTestCaseInfo(); if( startsWith( testCaseInfo.name, '#' ) ) Catch::cout() << '"' << testCaseInfo.name << '"'; else Catch::cout() << testCaseInfo.name; if ( config.listExtraInfo() ) Catch::cout() << "\t@" << testCaseInfo.lineInfo; Catch::cout() << std::endl; } return matchedTests; } struct TagInfo { TagInfo() : count ( 0 ) {} void add( std::string const& spelling ) { ++count; spellings.insert( spelling ); } std::string all() const { std::string out; for( std::set::const_iterator it = spellings.begin(), itEnd = spellings.end(); it != itEnd; ++it ) out += "[" + *it + "]"; return out; } std::set spellings; std::size_t count; }; inline std::size_t listTags( Config const& config ) { TestSpec testSpec = config.testSpec(); if( config.testSpec().hasFilters() ) Catch::cout() << "Tags for matching test cases:\n"; else { Catch::cout() << "All available tags:\n"; testSpec = TestSpecParser( ITagAliasRegistry::get() ).parse( "*" ).testSpec(); } std::map tagCounts; std::vector matchedTestCases = filterTests( getAllTestCasesSorted( config ), testSpec, config ); for( std::vector::const_iterator it = matchedTestCases.begin(), itEnd = matchedTestCases.end(); it != itEnd; ++it ) { for( std::set::const_iterator tagIt = it->getTestCaseInfo().tags.begin(), tagItEnd = it->getTestCaseInfo().tags.end(); tagIt != tagItEnd; ++tagIt ) { std::string tagName = *tagIt; std::string lcaseTagName = toLower( tagName ); std::map::iterator countIt = tagCounts.find( lcaseTagName ); if( countIt == tagCounts.end() ) countIt = tagCounts.insert( std::make_pair( lcaseTagName, TagInfo() ) ).first; countIt->second.add( tagName ); } } for( std::map::const_iterator countIt = tagCounts.begin(), countItEnd = tagCounts.end(); countIt != countItEnd; ++countIt ) { std::ostringstream oss; oss << " " << std::setw(2) << countIt->second.count << " "; Text wrapper( countIt->second.all(), TextAttributes() .setInitialIndent( 0 ) .setIndent( oss.str().size() ) .setWidth( CATCH_CONFIG_CONSOLE_WIDTH-10 ) ); Catch::cout() << oss.str() << wrapper << '\n'; } Catch::cout() << pluralise( tagCounts.size(), "tag" ) << '\n' << std::endl; return tagCounts.size(); } inline std::size_t listReporters( Config const& /*config*/ ) { Catch::cout() << "Available reporters:\n"; IReporterRegistry::FactoryMap const& factories = getRegistryHub().getReporterRegistry().getFactories(); IReporterRegistry::FactoryMap::const_iterator itBegin = factories.begin(), itEnd = factories.end(), it; std::size_t maxNameLen = 0; for(it = itBegin; it != itEnd; ++it ) maxNameLen = (std::max)( maxNameLen, it->first.size() ); for(it = itBegin; it != itEnd; ++it ) { Text wrapper( it->second->getDescription(), TextAttributes() .setInitialIndent( 0 ) .setIndent( 7+maxNameLen ) .setWidth( CATCH_CONFIG_CONSOLE_WIDTH - maxNameLen-8 ) ); Catch::cout() << " " << it->first << ':' << std::string( maxNameLen - it->first.size() + 2, ' ' ) << wrapper << '\n'; } Catch::cout() << std::endl; return factories.size(); } inline Option list( Config const& config ) { Option listedCount; if( config.listTests() || ( config.listExtraInfo() && !config.listTestNamesOnly() ) ) listedCount = listedCount.valueOr(0) + listTests( config ); if( config.listTestNamesOnly() ) listedCount = listedCount.valueOr(0) + listTestsNamesOnly( config ); if( config.listTags() ) listedCount = listedCount.valueOr(0) + listTags( config ); if( config.listReporters() ) listedCount = listedCount.valueOr(0) + listReporters( config ); return listedCount; } } // end namespace Catch // #included from: internal/catch_run_context.hpp #define TWOBLUECUBES_CATCH_RUNNER_IMPL_HPP_INCLUDED // #included from: catch_test_case_tracker.hpp #define TWOBLUECUBES_CATCH_TEST_CASE_TRACKER_HPP_INCLUDED #include #include #include #include #include CATCH_INTERNAL_SUPPRESS_ETD_WARNINGS namespace Catch { namespace TestCaseTracking { struct NameAndLocation { std::string name; SourceLineInfo location; NameAndLocation( std::string const& _name, SourceLineInfo const& _location ) : name( _name ), location( _location ) {} }; struct ITracker : SharedImpl<> { virtual ~ITracker(); // static queries virtual NameAndLocation const& nameAndLocation() const = 0; // dynamic queries virtual bool isComplete() const = 0; // Successfully completed or failed virtual bool isSuccessfullyCompleted() const = 0; virtual bool isOpen() const = 0; // Started but not complete virtual bool hasChildren() const = 0; virtual ITracker& parent() = 0; // actions virtual void close() = 0; // Successfully complete virtual void fail() = 0; virtual void markAsNeedingAnotherRun() = 0; virtual void addChild( Ptr const& child ) = 0; virtual ITracker* findChild( NameAndLocation const& nameAndLocation ) = 0; virtual void openChild() = 0; // Debug/ checking virtual bool isSectionTracker() const = 0; virtual bool isIndexTracker() const = 0; }; class TrackerContext { enum RunState { NotStarted, Executing, CompletedCycle }; Ptr m_rootTracker; ITracker* m_currentTracker; RunState m_runState; public: static TrackerContext& instance() { static TrackerContext s_instance; return s_instance; } TrackerContext() : m_currentTracker( CATCH_NULL ), m_runState( NotStarted ) {} ITracker& startRun(); void endRun() { m_rootTracker.reset(); m_currentTracker = CATCH_NULL; m_runState = NotStarted; } void startCycle() { m_currentTracker = m_rootTracker.get(); m_runState = Executing; } void completeCycle() { m_runState = CompletedCycle; } bool completedCycle() const { return m_runState == CompletedCycle; } ITracker& currentTracker() { return *m_currentTracker; } void setCurrentTracker( ITracker* tracker ) { m_currentTracker = tracker; } }; class TrackerBase : public ITracker { protected: enum CycleState { NotStarted, Executing, ExecutingChildren, NeedsAnotherRun, CompletedSuccessfully, Failed }; class TrackerHasName { NameAndLocation m_nameAndLocation; public: TrackerHasName( NameAndLocation const& nameAndLocation ) : m_nameAndLocation( nameAndLocation ) {} bool operator ()( Ptr const& tracker ) { return tracker->nameAndLocation().name == m_nameAndLocation.name && tracker->nameAndLocation().location == m_nameAndLocation.location; } }; typedef std::vector > Children; NameAndLocation m_nameAndLocation; TrackerContext& m_ctx; ITracker* m_parent; Children m_children; CycleState m_runState; public: TrackerBase( NameAndLocation const& nameAndLocation, TrackerContext& ctx, ITracker* parent ) : m_nameAndLocation( nameAndLocation ), m_ctx( ctx ), m_parent( parent ), m_runState( NotStarted ) {} virtual ~TrackerBase(); virtual NameAndLocation const& nameAndLocation() const CATCH_OVERRIDE { return m_nameAndLocation; } virtual bool isComplete() const CATCH_OVERRIDE { return m_runState == CompletedSuccessfully || m_runState == Failed; } virtual bool isSuccessfullyCompleted() const CATCH_OVERRIDE { return m_runState == CompletedSuccessfully; } virtual bool isOpen() const CATCH_OVERRIDE { return m_runState != NotStarted && !isComplete(); } virtual bool hasChildren() const CATCH_OVERRIDE { return !m_children.empty(); } virtual void addChild( Ptr const& child ) CATCH_OVERRIDE { m_children.push_back( child ); } virtual ITracker* findChild( NameAndLocation const& nameAndLocation ) CATCH_OVERRIDE { Children::const_iterator it = std::find_if( m_children.begin(), m_children.end(), TrackerHasName( nameAndLocation ) ); return( it != m_children.end() ) ? it->get() : CATCH_NULL; } virtual ITracker& parent() CATCH_OVERRIDE { assert( m_parent ); // Should always be non-null except for root return *m_parent; } virtual void openChild() CATCH_OVERRIDE { if( m_runState != ExecutingChildren ) { m_runState = ExecutingChildren; if( m_parent ) m_parent->openChild(); } } virtual bool isSectionTracker() const CATCH_OVERRIDE { return false; } virtual bool isIndexTracker() const CATCH_OVERRIDE { return false; } void open() { m_runState = Executing; moveToThis(); if( m_parent ) m_parent->openChild(); } virtual void close() CATCH_OVERRIDE { // Close any still open children (e.g. generators) while( &m_ctx.currentTracker() != this ) m_ctx.currentTracker().close(); switch( m_runState ) { case NotStarted: case CompletedSuccessfully: case Failed: throw std::logic_error( "Illogical state" ); case NeedsAnotherRun: break;; case Executing: m_runState = CompletedSuccessfully; break; case ExecutingChildren: if( m_children.empty() || m_children.back()->isComplete() ) m_runState = CompletedSuccessfully; break; default: throw std::logic_error( "Unexpected state" ); } moveToParent(); m_ctx.completeCycle(); } virtual void fail() CATCH_OVERRIDE { m_runState = Failed; if( m_parent ) m_parent->markAsNeedingAnotherRun(); moveToParent(); m_ctx.completeCycle(); } virtual void markAsNeedingAnotherRun() CATCH_OVERRIDE { m_runState = NeedsAnotherRun; } private: void moveToParent() { assert( m_parent ); m_ctx.setCurrentTracker( m_parent ); } void moveToThis() { m_ctx.setCurrentTracker( this ); } }; class SectionTracker : public TrackerBase { std::vector m_filters; public: SectionTracker( NameAndLocation const& nameAndLocation, TrackerContext& ctx, ITracker* parent ) : TrackerBase( nameAndLocation, ctx, parent ) { if( parent ) { while( !parent->isSectionTracker() ) parent = &parent->parent(); SectionTracker& parentSection = static_cast( *parent ); addNextFilters( parentSection.m_filters ); } } virtual ~SectionTracker(); virtual bool isSectionTracker() const CATCH_OVERRIDE { return true; } static SectionTracker& acquire( TrackerContext& ctx, NameAndLocation const& nameAndLocation ) { SectionTracker* section = CATCH_NULL; ITracker& currentTracker = ctx.currentTracker(); if( ITracker* childTracker = currentTracker.findChild( nameAndLocation ) ) { assert( childTracker ); assert( childTracker->isSectionTracker() ); section = static_cast( childTracker ); } else { section = new SectionTracker( nameAndLocation, ctx, ¤tTracker ); currentTracker.addChild( section ); } if( !ctx.completedCycle() ) section->tryOpen(); return *section; } void tryOpen() { if( !isComplete() && (m_filters.empty() || m_filters[0].empty() || m_filters[0] == m_nameAndLocation.name ) ) open(); } void addInitialFilters( std::vector const& filters ) { if( !filters.empty() ) { m_filters.push_back(""); // Root - should never be consulted m_filters.push_back(""); // Test Case - not a section filter m_filters.insert( m_filters.end(), filters.begin(), filters.end() ); } } void addNextFilters( std::vector const& filters ) { if( filters.size() > 1 ) m_filters.insert( m_filters.end(), ++filters.begin(), filters.end() ); } }; class IndexTracker : public TrackerBase { int m_size; int m_index; public: IndexTracker( NameAndLocation const& nameAndLocation, TrackerContext& ctx, ITracker* parent, int size ) : TrackerBase( nameAndLocation, ctx, parent ), m_size( size ), m_index( -1 ) {} virtual ~IndexTracker(); virtual bool isIndexTracker() const CATCH_OVERRIDE { return true; } static IndexTracker& acquire( TrackerContext& ctx, NameAndLocation const& nameAndLocation, int size ) { IndexTracker* tracker = CATCH_NULL; ITracker& currentTracker = ctx.currentTracker(); if( ITracker* childTracker = currentTracker.findChild( nameAndLocation ) ) { assert( childTracker ); assert( childTracker->isIndexTracker() ); tracker = static_cast( childTracker ); } else { tracker = new IndexTracker( nameAndLocation, ctx, ¤tTracker, size ); currentTracker.addChild( tracker ); } if( !ctx.completedCycle() && !tracker->isComplete() ) { if( tracker->m_runState != ExecutingChildren && tracker->m_runState != NeedsAnotherRun ) tracker->moveNext(); tracker->open(); } return *tracker; } int index() const { return m_index; } void moveNext() { m_index++; m_children.clear(); } virtual void close() CATCH_OVERRIDE { TrackerBase::close(); if( m_runState == CompletedSuccessfully && m_index < m_size-1 ) m_runState = Executing; } }; inline ITracker& TrackerContext::startRun() { m_rootTracker = new SectionTracker( NameAndLocation( "{root}", CATCH_INTERNAL_LINEINFO ), *this, CATCH_NULL ); m_currentTracker = CATCH_NULL; m_runState = Executing; return *m_rootTracker; } } // namespace TestCaseTracking using TestCaseTracking::ITracker; using TestCaseTracking::TrackerContext; using TestCaseTracking::SectionTracker; using TestCaseTracking::IndexTracker; } // namespace Catch CATCH_INTERNAL_UNSUPPRESS_ETD_WARNINGS // #included from: catch_fatal_condition.hpp #define TWOBLUECUBES_CATCH_FATAL_CONDITION_H_INCLUDED namespace Catch { // Report the error condition inline void reportFatal( std::string const& message ) { IContext& context = Catch::getCurrentContext(); IResultCapture* resultCapture = context.getResultCapture(); resultCapture->handleFatalErrorCondition( message ); } } // namespace Catch #if defined ( CATCH_PLATFORM_WINDOWS ) ///////////////////////////////////////// // #included from: catch_windows_h_proxy.h #define TWOBLUECUBES_CATCH_WINDOWS_H_PROXY_H_INCLUDED #ifdef CATCH_DEFINES_NOMINMAX # define NOMINMAX #endif #ifdef CATCH_DEFINES_WIN32_LEAN_AND_MEAN # define WIN32_LEAN_AND_MEAN #endif #ifdef __AFXDLL #include #else #include #endif #ifdef CATCH_DEFINES_NOMINMAX # undef NOMINMAX #endif #ifdef CATCH_DEFINES_WIN32_LEAN_AND_MEAN # undef WIN32_LEAN_AND_MEAN #endif # if !defined ( CATCH_CONFIG_WINDOWS_SEH ) namespace Catch { struct FatalConditionHandler { void reset() {} }; } # else // CATCH_CONFIG_WINDOWS_SEH is defined namespace Catch { struct SignalDefs { DWORD id; const char* name; }; extern SignalDefs signalDefs[]; // There is no 1-1 mapping between signals and windows exceptions. // Windows can easily distinguish between SO and SigSegV, // but SigInt, SigTerm, etc are handled differently. SignalDefs signalDefs[] = { { EXCEPTION_ILLEGAL_INSTRUCTION, "SIGILL - Illegal instruction signal" }, { EXCEPTION_STACK_OVERFLOW, "SIGSEGV - Stack overflow" }, { EXCEPTION_ACCESS_VIOLATION, "SIGSEGV - Segmentation violation signal" }, { EXCEPTION_INT_DIVIDE_BY_ZERO, "Divide by zero error" }, }; struct FatalConditionHandler { static LONG CALLBACK handleVectoredException(PEXCEPTION_POINTERS ExceptionInfo) { for (int i = 0; i < sizeof(signalDefs) / sizeof(SignalDefs); ++i) { if (ExceptionInfo->ExceptionRecord->ExceptionCode == signalDefs[i].id) { reportFatal(signalDefs[i].name); } } // If its not an exception we care about, pass it along. // This stops us from eating debugger breaks etc. return EXCEPTION_CONTINUE_SEARCH; } FatalConditionHandler() { isSet = true; // 32k seems enough for Catch to handle stack overflow, // but the value was found experimentally, so there is no strong guarantee guaranteeSize = 32 * 1024; exceptionHandlerHandle = CATCH_NULL; // Register as first handler in current chain exceptionHandlerHandle = AddVectoredExceptionHandler(1, handleVectoredException); // Pass in guarantee size to be filled SetThreadStackGuarantee(&guaranteeSize); } static void reset() { if (isSet) { // Unregister handler and restore the old guarantee RemoveVectoredExceptionHandler(exceptionHandlerHandle); SetThreadStackGuarantee(&guaranteeSize); exceptionHandlerHandle = CATCH_NULL; isSet = false; } } ~FatalConditionHandler() { reset(); } private: static bool isSet; static ULONG guaranteeSize; static PVOID exceptionHandlerHandle; }; bool FatalConditionHandler::isSet = false; ULONG FatalConditionHandler::guaranteeSize = 0; PVOID FatalConditionHandler::exceptionHandlerHandle = CATCH_NULL; } // namespace Catch # endif // CATCH_CONFIG_WINDOWS_SEH #else // Not Windows - assumed to be POSIX compatible ////////////////////////// # if !defined(CATCH_CONFIG_POSIX_SIGNALS) namespace Catch { struct FatalConditionHandler { void reset() {} }; } # else // CATCH_CONFIG_POSIX_SIGNALS is defined #include namespace Catch { struct SignalDefs { int id; const char* name; }; extern SignalDefs signalDefs[]; SignalDefs signalDefs[] = { { SIGINT, "SIGINT - Terminal interrupt signal" }, { SIGILL, "SIGILL - Illegal instruction signal" }, { SIGFPE, "SIGFPE - Floating point error signal" }, { SIGSEGV, "SIGSEGV - Segmentation violation signal" }, { SIGTERM, "SIGTERM - Termination request signal" }, { SIGABRT, "SIGABRT - Abort (abnormal termination) signal" } }; struct FatalConditionHandler { static bool isSet; static struct sigaction oldSigActions [sizeof(signalDefs)/sizeof(SignalDefs)]; static stack_t oldSigStack; static char altStackMem[SIGSTKSZ]; static void handleSignal( int sig ) { std::string name = ""; for (std::size_t i = 0; i < sizeof(signalDefs) / sizeof(SignalDefs); ++i) { SignalDefs &def = signalDefs[i]; if (sig == def.id) { name = def.name; break; } } reset(); reportFatal(name); raise( sig ); } FatalConditionHandler() { isSet = true; stack_t sigStack; sigStack.ss_sp = altStackMem; sigStack.ss_size = SIGSTKSZ; sigStack.ss_flags = 0; sigaltstack(&sigStack, &oldSigStack); struct sigaction sa = { 0 }; sa.sa_handler = handleSignal; sa.sa_flags = SA_ONSTACK; for (std::size_t i = 0; i < sizeof(signalDefs)/sizeof(SignalDefs); ++i) { sigaction(signalDefs[i].id, &sa, &oldSigActions[i]); } } ~FatalConditionHandler() { reset(); } static void reset() { if( isSet ) { // Set signals back to previous values -- hopefully nobody overwrote them in the meantime for( std::size_t i = 0; i < sizeof(signalDefs)/sizeof(SignalDefs); ++i ) { sigaction(signalDefs[i].id, &oldSigActions[i], CATCH_NULL); } // Return the old stack sigaltstack(&oldSigStack, CATCH_NULL); isSet = false; } } }; bool FatalConditionHandler::isSet = false; struct sigaction FatalConditionHandler::oldSigActions[sizeof(signalDefs)/sizeof(SignalDefs)] = {}; stack_t FatalConditionHandler::oldSigStack = {}; char FatalConditionHandler::altStackMem[SIGSTKSZ] = {}; } // namespace Catch # endif // CATCH_CONFIG_POSIX_SIGNALS #endif // not Windows #include #include namespace Catch { class StreamRedirect { public: StreamRedirect( std::ostream& stream, std::string& targetString ) : m_stream( stream ), m_prevBuf( stream.rdbuf() ), m_targetString( targetString ) { stream.rdbuf( m_oss.rdbuf() ); } ~StreamRedirect() { m_targetString += m_oss.str(); m_stream.rdbuf( m_prevBuf ); } private: std::ostream& m_stream; std::streambuf* m_prevBuf; std::ostringstream m_oss; std::string& m_targetString; }; // StdErr has two constituent streams in C++, std::cerr and std::clog // This means that we need to redirect 2 streams into 1 to keep proper // order of writes and cannot use StreamRedirect on its own class StdErrRedirect { public: StdErrRedirect(std::string& targetString) :m_cerrBuf( cerr().rdbuf() ), m_clogBuf(clog().rdbuf()), m_targetString(targetString){ cerr().rdbuf(m_oss.rdbuf()); clog().rdbuf(m_oss.rdbuf()); } ~StdErrRedirect() { m_targetString += m_oss.str(); cerr().rdbuf(m_cerrBuf); clog().rdbuf(m_clogBuf); } private: std::streambuf* m_cerrBuf; std::streambuf* m_clogBuf; std::ostringstream m_oss; std::string& m_targetString; }; /////////////////////////////////////////////////////////////////////////// class RunContext : public IResultCapture, public IRunner { RunContext( RunContext const& ); void operator =( RunContext const& ); public: explicit RunContext( Ptr const& _config, Ptr const& reporter ) : m_runInfo( _config->name() ), m_context( getCurrentMutableContext() ), m_activeTestCase( CATCH_NULL ), m_config( _config ), m_reporter( reporter ), m_shouldReportUnexpected ( true ) { m_context.setRunner( this ); m_context.setConfig( m_config ); m_context.setResultCapture( this ); m_reporter->testRunStarting( m_runInfo ); } virtual ~RunContext() { m_reporter->testRunEnded( TestRunStats( m_runInfo, m_totals, aborting() ) ); } void testGroupStarting( std::string const& testSpec, std::size_t groupIndex, std::size_t groupsCount ) { m_reporter->testGroupStarting( GroupInfo( testSpec, groupIndex, groupsCount ) ); } void testGroupEnded( std::string const& testSpec, Totals const& totals, std::size_t groupIndex, std::size_t groupsCount ) { m_reporter->testGroupEnded( TestGroupStats( GroupInfo( testSpec, groupIndex, groupsCount ), totals, aborting() ) ); } Totals runTest( TestCase const& testCase ) { Totals prevTotals = m_totals; std::string redirectedCout; std::string redirectedCerr; TestCaseInfo testInfo = testCase.getTestCaseInfo(); m_reporter->testCaseStarting( testInfo ); m_activeTestCase = &testCase; do { ITracker& rootTracker = m_trackerContext.startRun(); assert( rootTracker.isSectionTracker() ); static_cast( rootTracker ).addInitialFilters( m_config->getSectionsToRun() ); do { m_trackerContext.startCycle(); m_testCaseTracker = &SectionTracker::acquire( m_trackerContext, TestCaseTracking::NameAndLocation( testInfo.name, testInfo.lineInfo ) ); runCurrentTest( redirectedCout, redirectedCerr ); } while( !m_testCaseTracker->isSuccessfullyCompleted() && !aborting() ); } // !TBD: deprecated - this will be replaced by indexed trackers while( getCurrentContext().advanceGeneratorsForCurrentTest() && !aborting() ); Totals deltaTotals = m_totals.delta( prevTotals ); if( testInfo.expectedToFail() && deltaTotals.testCases.passed > 0 ) { deltaTotals.assertions.failed++; deltaTotals.testCases.passed--; deltaTotals.testCases.failed++; } m_totals.testCases += deltaTotals.testCases; m_reporter->testCaseEnded( TestCaseStats( testInfo, deltaTotals, redirectedCout, redirectedCerr, aborting() ) ); m_activeTestCase = CATCH_NULL; m_testCaseTracker = CATCH_NULL; return deltaTotals; } Ptr config() const { return m_config; } private: // IResultCapture virtual void assertionEnded( AssertionResult const& result ) { if( result.getResultType() == ResultWas::Ok ) { m_totals.assertions.passed++; } else if( !result.isOk() ) { if( m_activeTestCase->getTestCaseInfo().okToFail() ) m_totals.assertions.failedButOk++; else m_totals.assertions.failed++; } // We have no use for the return value (whether messages should be cleared), because messages were made scoped // and should be let to clear themselves out. static_cast(m_reporter->assertionEnded(AssertionStats(result, m_messages, m_totals))); // Reset working state m_lastAssertionInfo = AssertionInfo( "", m_lastAssertionInfo.lineInfo, "{Unknown expression after the reported line}" , m_lastAssertionInfo.resultDisposition ); m_lastResult = result; } virtual bool lastAssertionPassed() { return m_totals.assertions.passed == (m_prevPassed + 1); } virtual void assertionPassed() { m_totals.assertions.passed++; m_lastAssertionInfo.capturedExpression = "{Unknown expression after the reported line}"; m_lastAssertionInfo.macroName = ""; } virtual void assertionRun() { m_prevPassed = m_totals.assertions.passed; } virtual bool sectionStarted ( SectionInfo const& sectionInfo, Counts& assertions ) { ITracker& sectionTracker = SectionTracker::acquire( m_trackerContext, TestCaseTracking::NameAndLocation( sectionInfo.name, sectionInfo.lineInfo ) ); if( !sectionTracker.isOpen() ) return false; m_activeSections.push_back( §ionTracker ); m_lastAssertionInfo.lineInfo = sectionInfo.lineInfo; m_reporter->sectionStarting( sectionInfo ); assertions = m_totals.assertions; return true; } bool testForMissingAssertions( Counts& assertions ) { if( assertions.total() != 0 ) return false; if( !m_config->warnAboutMissingAssertions() ) return false; if( m_trackerContext.currentTracker().hasChildren() ) return false; m_totals.assertions.failed++; assertions.failed++; return true; } virtual void sectionEnded( SectionEndInfo const& endInfo ) { Counts assertions = m_totals.assertions - endInfo.prevAssertions; bool missingAssertions = testForMissingAssertions( assertions ); if( !m_activeSections.empty() ) { m_activeSections.back()->close(); m_activeSections.pop_back(); } m_reporter->sectionEnded( SectionStats( endInfo.sectionInfo, assertions, endInfo.durationInSeconds, missingAssertions ) ); m_messages.clear(); } virtual void sectionEndedEarly( SectionEndInfo const& endInfo ) { if( m_unfinishedSections.empty() ) m_activeSections.back()->fail(); else m_activeSections.back()->close(); m_activeSections.pop_back(); m_unfinishedSections.push_back( endInfo ); } virtual void pushScopedMessage( MessageInfo const& message ) { m_messages.push_back( message ); } virtual void popScopedMessage( MessageInfo const& message ) { m_messages.erase( std::remove( m_messages.begin(), m_messages.end(), message ), m_messages.end() ); } virtual std::string getCurrentTestName() const { return m_activeTestCase ? m_activeTestCase->getTestCaseInfo().name : std::string(); } virtual const AssertionResult* getLastResult() const { return &m_lastResult; } virtual void exceptionEarlyReported() { m_shouldReportUnexpected = false; } virtual void handleFatalErrorCondition( std::string const& message ) { // Don't rebuild the result -- the stringification itself can cause more fatal errors // Instead, fake a result data. AssertionResultData tempResult; tempResult.resultType = ResultWas::FatalErrorCondition; tempResult.message = message; AssertionResult result(m_lastAssertionInfo, tempResult); getResultCapture().assertionEnded(result); handleUnfinishedSections(); // Recreate section for test case (as we will lose the one that was in scope) TestCaseInfo const& testCaseInfo = m_activeTestCase->getTestCaseInfo(); SectionInfo testCaseSection( testCaseInfo.lineInfo, testCaseInfo.name, testCaseInfo.description ); Counts assertions; assertions.failed = 1; SectionStats testCaseSectionStats( testCaseSection, assertions, 0, false ); m_reporter->sectionEnded( testCaseSectionStats ); TestCaseInfo testInfo = m_activeTestCase->getTestCaseInfo(); Totals deltaTotals; deltaTotals.testCases.failed = 1; deltaTotals.assertions.failed = 1; m_reporter->testCaseEnded( TestCaseStats( testInfo, deltaTotals, std::string(), std::string(), false ) ); m_totals.testCases.failed++; testGroupEnded( std::string(), m_totals, 1, 1 ); m_reporter->testRunEnded( TestRunStats( m_runInfo, m_totals, false ) ); } public: // !TBD We need to do this another way! bool aborting() const { return m_totals.assertions.failed == static_cast( m_config->abortAfter() ); } private: void runCurrentTest( std::string& redirectedCout, std::string& redirectedCerr ) { TestCaseInfo const& testCaseInfo = m_activeTestCase->getTestCaseInfo(); SectionInfo testCaseSection( testCaseInfo.lineInfo, testCaseInfo.name, testCaseInfo.description ); m_reporter->sectionStarting( testCaseSection ); Counts prevAssertions = m_totals.assertions; double duration = 0; m_shouldReportUnexpected = true; try { m_lastAssertionInfo = AssertionInfo( "TEST_CASE", testCaseInfo.lineInfo, "", ResultDisposition::Normal ); seedRng( *m_config ); Timer timer; timer.start(); if( m_reporter->getPreferences().shouldRedirectStdOut ) { StreamRedirect coutRedir( Catch::cout(), redirectedCout ); StdErrRedirect errRedir( redirectedCerr ); invokeActiveTestCase(); } else { invokeActiveTestCase(); } duration = timer.getElapsedSeconds(); } catch( TestFailureException& ) { // This just means the test was aborted due to failure } catch(...) { // Under CATCH_CONFIG_FAST_COMPILE, unexpected exceptions under REQUIRE assertions // are reported without translation at the point of origin. if (m_shouldReportUnexpected) { makeUnexpectedResultBuilder().useActiveException(); } } m_testCaseTracker->close(); handleUnfinishedSections(); m_messages.clear(); Counts assertions = m_totals.assertions - prevAssertions; bool missingAssertions = testForMissingAssertions( assertions ); SectionStats testCaseSectionStats( testCaseSection, assertions, duration, missingAssertions ); m_reporter->sectionEnded( testCaseSectionStats ); } void invokeActiveTestCase() { FatalConditionHandler fatalConditionHandler; // Handle signals m_activeTestCase->invoke(); fatalConditionHandler.reset(); } private: ResultBuilder makeUnexpectedResultBuilder() const { return ResultBuilder( m_lastAssertionInfo.macroName, m_lastAssertionInfo.lineInfo, m_lastAssertionInfo.capturedExpression, m_lastAssertionInfo.resultDisposition ); } void handleUnfinishedSections() { // If sections ended prematurely due to an exception we stored their // infos here so we can tear them down outside the unwind process. for( std::vector::const_reverse_iterator it = m_unfinishedSections.rbegin(), itEnd = m_unfinishedSections.rend(); it != itEnd; ++it ) sectionEnded( *it ); m_unfinishedSections.clear(); } TestRunInfo m_runInfo; IMutableContext& m_context; TestCase const* m_activeTestCase; ITracker* m_testCaseTracker; ITracker* m_currentSectionTracker; AssertionResult m_lastResult; Ptr m_config; Totals m_totals; Ptr m_reporter; std::vector m_messages; AssertionInfo m_lastAssertionInfo; std::vector m_unfinishedSections; std::vector m_activeSections; TrackerContext m_trackerContext; size_t m_prevPassed; bool m_shouldReportUnexpected; }; IResultCapture& getResultCapture() { if( IResultCapture* capture = getCurrentContext().getResultCapture() ) return *capture; else throw std::logic_error( "No result capture instance" ); } } // end namespace Catch // #included from: internal/catch_version.h #define TWOBLUECUBES_CATCH_VERSION_H_INCLUDED namespace Catch { // Versioning information struct Version { Version( unsigned int _majorVersion, unsigned int _minorVersion, unsigned int _patchNumber, char const * const _branchName, unsigned int _buildNumber ); unsigned int const majorVersion; unsigned int const minorVersion; unsigned int const patchNumber; // buildNumber is only used if branchName is not null char const * const branchName; unsigned int const buildNumber; friend std::ostream& operator << ( std::ostream& os, Version const& version ); private: void operator=( Version const& ); }; inline Version libraryVersion(); } #include #include #include namespace Catch { Ptr createReporter( std::string const& reporterName, Ptr const& config ) { Ptr reporter = getRegistryHub().getReporterRegistry().create( reporterName, config.get() ); if( !reporter ) { std::ostringstream oss; oss << "No reporter registered with name: '" << reporterName << "'"; throw std::domain_error( oss.str() ); } return reporter; } #if !defined(CATCH_CONFIG_DEFAULT_REPORTER) #define CATCH_CONFIG_DEFAULT_REPORTER "console" #endif Ptr makeReporter( Ptr const& config ) { std::vector reporters = config->getReporterNames(); if( reporters.empty() ) reporters.push_back( CATCH_CONFIG_DEFAULT_REPORTER ); Ptr reporter; for( std::vector::const_iterator it = reporters.begin(), itEnd = reporters.end(); it != itEnd; ++it ) reporter = addReporter( reporter, createReporter( *it, config ) ); return reporter; } Ptr addListeners( Ptr const& config, Ptr reporters ) { IReporterRegistry::Listeners listeners = getRegistryHub().getReporterRegistry().getListeners(); for( IReporterRegistry::Listeners::const_iterator it = listeners.begin(), itEnd = listeners.end(); it != itEnd; ++it ) reporters = addReporter(reporters, (*it)->create( ReporterConfig( config ) ) ); return reporters; } Totals runTests( Ptr const& config ) { Ptr iconfig = config.get(); Ptr reporter = makeReporter( config ); reporter = addListeners( iconfig, reporter ); RunContext context( iconfig, reporter ); Totals totals; context.testGroupStarting( config->name(), 1, 1 ); TestSpec testSpec = config->testSpec(); if( !testSpec.hasFilters() ) testSpec = TestSpecParser( ITagAliasRegistry::get() ).parse( "~[.]" ).testSpec(); // All not hidden tests std::vector const& allTestCases = getAllTestCasesSorted( *iconfig ); for( std::vector::const_iterator it = allTestCases.begin(), itEnd = allTestCases.end(); it != itEnd; ++it ) { if( !context.aborting() && matchTest( *it, testSpec, *iconfig ) ) totals += context.runTest( *it ); else reporter->skipTest( *it ); } context.testGroupEnded( iconfig->name(), totals, 1, 1 ); return totals; } void applyFilenamesAsTags( IConfig const& config ) { std::vector const& tests = getAllTestCasesSorted( config ); for(std::size_t i = 0; i < tests.size(); ++i ) { TestCase& test = const_cast( tests[i] ); std::set tags = test.tags; std::string filename = test.lineInfo.file; std::string::size_type lastSlash = filename.find_last_of( "\\/" ); if( lastSlash != std::string::npos ) filename = filename.substr( lastSlash+1 ); std::string::size_type lastDot = filename.find_last_of( '.' ); if( lastDot != std::string::npos ) filename = filename.substr( 0, lastDot ); tags.insert( '#' + filename ); setTags( test, tags ); } } class Session : NonCopyable { static bool alreadyInstantiated; public: struct OnUnusedOptions { enum DoWhat { Ignore, Fail }; }; Session() : m_cli( makeCommandLineParser() ) { if( alreadyInstantiated ) { std::string msg = "Only one instance of Catch::Session can ever be used"; Catch::cerr() << msg << std::endl; throw std::logic_error( msg ); } alreadyInstantiated = true; } ~Session() { Catch::cleanUp(); } void showHelp( std::string const& processName ) { Catch::cout() << "\nCatch v" << libraryVersion() << "\n"; m_cli.usage( Catch::cout(), processName ); Catch::cout() << "For more detail usage please see the project docs\n" << std::endl; } void libIdentify() { Catch::cout() << std::left << std::setw(16) << "description: " << "A Catch test executable\n" << std::left << std::setw(16) << "category: " << "testframework\n" << std::left << std::setw(16) << "framework: " << "Catch Test\n" << std::left << std::setw(16) << "version: " << libraryVersion() << std::endl; } int applyCommandLine( int argc, char const* const* const argv, OnUnusedOptions::DoWhat unusedOptionBehaviour = OnUnusedOptions::Fail ) { try { m_cli.setThrowOnUnrecognisedTokens( unusedOptionBehaviour == OnUnusedOptions::Fail ); m_unusedTokens = m_cli.parseInto( Clara::argsToVector( argc, argv ), m_configData ); if( m_configData.showHelp ) showHelp( m_configData.processName ); if( m_configData.libIdentify ) libIdentify(); m_config.reset(); } catch( std::exception& ex ) { { Colour colourGuard( Colour::Red ); Catch::cerr() << "\nError(s) in input:\n" << Text( ex.what(), TextAttributes().setIndent(2) ) << "\n\n"; } m_cli.usage( Catch::cout(), m_configData.processName ); return (std::numeric_limits::max)(); } return 0; } void useConfigData( ConfigData const& _configData ) { m_configData = _configData; m_config.reset(); } int run( int argc, char const* const* const argv ) { int returnCode = applyCommandLine( argc, argv ); if( returnCode == 0 ) returnCode = run(); return returnCode; } #if defined(WIN32) && defined(UNICODE) int run( int argc, wchar_t const* const* const argv ) { char **utf8Argv = new char *[ argc ]; for ( int i = 0; i < argc; ++i ) { int bufSize = WideCharToMultiByte( CP_UTF8, 0, argv[i], -1, NULL, 0, NULL, NULL ); utf8Argv[ i ] = new char[ bufSize ]; WideCharToMultiByte( CP_UTF8, 0, argv[i], -1, utf8Argv[i], bufSize, NULL, NULL ); } int returnCode = applyCommandLine( argc, utf8Argv ); if( returnCode == 0 ) returnCode = run(); for ( int i = 0; i < argc; ++i ) delete [] utf8Argv[ i ]; delete [] utf8Argv; return returnCode; } #endif int run() { if( ( m_configData.waitForKeypress & WaitForKeypress::BeforeStart ) != 0 ) { Catch::cout() << "...waiting for enter/ return before starting" << std::endl; static_cast(std::getchar()); } int exitCode = runInternal(); if( ( m_configData.waitForKeypress & WaitForKeypress::BeforeExit ) != 0 ) { Catch::cout() << "...waiting for enter/ return before exiting, with code: " << exitCode << std::endl; static_cast(std::getchar()); } return exitCode; } Clara::CommandLine const& cli() const { return m_cli; } std::vector const& unusedTokens() const { return m_unusedTokens; } ConfigData& configData() { return m_configData; } Config& config() { if( !m_config ) m_config = new Config( m_configData ); return *m_config; } private: int runInternal() { if( m_configData.showHelp || m_configData.libIdentify ) return 0; try { config(); // Force config to be constructed seedRng( *m_config ); if( m_configData.filenamesAsTags ) applyFilenamesAsTags( *m_config ); // Handle list request if( Option listed = list( config() ) ) return static_cast( *listed ); return static_cast( runTests( m_config ).assertions.failed ); } catch( std::exception& ex ) { Catch::cerr() << ex.what() << std::endl; return (std::numeric_limits::max)(); } } Clara::CommandLine m_cli; std::vector m_unusedTokens; ConfigData m_configData; Ptr m_config; }; bool Session::alreadyInstantiated = false; } // end namespace Catch // #included from: catch_registry_hub.hpp #define TWOBLUECUBES_CATCH_REGISTRY_HUB_HPP_INCLUDED // #included from: catch_test_case_registry_impl.hpp #define TWOBLUECUBES_CATCH_TEST_CASE_REGISTRY_IMPL_HPP_INCLUDED #include #include #include #include namespace Catch { struct RandomNumberGenerator { typedef unsigned int result_type; result_type operator()( result_type n ) const { return std::rand() % n; } #ifdef CATCH_CONFIG_CPP11_SHUFFLE static constexpr result_type (min)() { return 0; } static constexpr result_type (max)() { return 1000000; } result_type operator()() const { return std::rand() % (max)(); } #endif template static void shuffle( V& vector ) { RandomNumberGenerator rng; #ifdef CATCH_CONFIG_CPP11_SHUFFLE std::shuffle( vector.begin(), vector.end(), rng ); #else std::random_shuffle( vector.begin(), vector.end(), rng ); #endif } }; inline std::vector sortTests( IConfig const& config, std::vector const& unsortedTestCases ) { std::vector sorted = unsortedTestCases; switch( config.runOrder() ) { case RunTests::InLexicographicalOrder: std::sort( sorted.begin(), sorted.end() ); break; case RunTests::InRandomOrder: { seedRng( config ); RandomNumberGenerator::shuffle( sorted ); } break; case RunTests::InDeclarationOrder: // already in declaration order break; } return sorted; } bool matchTest( TestCase const& testCase, TestSpec const& testSpec, IConfig const& config ) { return testSpec.matches( testCase ) && ( config.allowThrows() || !testCase.throws() ); } void enforceNoDuplicateTestCases( std::vector const& functions ) { std::set seenFunctions; for( std::vector::const_iterator it = functions.begin(), itEnd = functions.end(); it != itEnd; ++it ) { std::pair::const_iterator, bool> prev = seenFunctions.insert( *it ); if( !prev.second ) { std::ostringstream ss; ss << Colour( Colour::Red ) << "error: TEST_CASE( \"" << it->name << "\" ) already defined.\n" << "\tFirst seen at " << prev.first->getTestCaseInfo().lineInfo << '\n' << "\tRedefined at " << it->getTestCaseInfo().lineInfo << std::endl; throw std::runtime_error(ss.str()); } } } std::vector filterTests( std::vector const& testCases, TestSpec const& testSpec, IConfig const& config ) { std::vector filtered; filtered.reserve( testCases.size() ); for( std::vector::const_iterator it = testCases.begin(), itEnd = testCases.end(); it != itEnd; ++it ) if( matchTest( *it, testSpec, config ) ) filtered.push_back( *it ); return filtered; } std::vector const& getAllTestCasesSorted( IConfig const& config ) { return getRegistryHub().getTestCaseRegistry().getAllTestsSorted( config ); } class TestRegistry : public ITestCaseRegistry { public: TestRegistry() : m_currentSortOrder( RunTests::InDeclarationOrder ), m_unnamedCount( 0 ) {} virtual ~TestRegistry(); virtual void registerTest( TestCase const& testCase ) { std::string name = testCase.getTestCaseInfo().name; if( name.empty() ) { std::ostringstream oss; oss << "Anonymous test case " << ++m_unnamedCount; return registerTest( testCase.withName( oss.str() ) ); } m_functions.push_back( testCase ); } virtual std::vector const& getAllTests() const { return m_functions; } virtual std::vector const& getAllTestsSorted( IConfig const& config ) const { if( m_sortedFunctions.empty() ) enforceNoDuplicateTestCases( m_functions ); if( m_currentSortOrder != config.runOrder() || m_sortedFunctions.empty() ) { m_sortedFunctions = sortTests( config, m_functions ); m_currentSortOrder = config.runOrder(); } return m_sortedFunctions; } private: std::vector m_functions; mutable RunTests::InWhatOrder m_currentSortOrder; mutable std::vector m_sortedFunctions; size_t m_unnamedCount; std::ios_base::Init m_ostreamInit; // Forces cout/ cerr to be initialised }; /////////////////////////////////////////////////////////////////////////// class FreeFunctionTestCase : public SharedImpl { public: FreeFunctionTestCase( TestFunction fun ) : m_fun( fun ) {} virtual void invoke() const { m_fun(); } private: virtual ~FreeFunctionTestCase(); TestFunction m_fun; }; inline std::string extractClassName( std::string const& classOrQualifiedMethodName ) { std::string className = classOrQualifiedMethodName; if( startsWith( className, '&' ) ) { std::size_t lastColons = className.rfind( "::" ); std::size_t penultimateColons = className.rfind( "::", lastColons-1 ); if( penultimateColons == std::string::npos ) penultimateColons = 1; className = className.substr( penultimateColons, lastColons-penultimateColons ); } return className; } void registerTestCase ( ITestCase* testCase, char const* classOrQualifiedMethodName, NameAndDesc const& nameAndDesc, SourceLineInfo const& lineInfo ) { getMutableRegistryHub().registerTest ( makeTestCase ( testCase, extractClassName( classOrQualifiedMethodName ), nameAndDesc.name, nameAndDesc.description, lineInfo ) ); } void registerTestCaseFunction ( TestFunction function, SourceLineInfo const& lineInfo, NameAndDesc const& nameAndDesc ) { registerTestCase( new FreeFunctionTestCase( function ), "", nameAndDesc, lineInfo ); } /////////////////////////////////////////////////////////////////////////// AutoReg::AutoReg ( TestFunction function, SourceLineInfo const& lineInfo, NameAndDesc const& nameAndDesc ) { registerTestCaseFunction( function, lineInfo, nameAndDesc ); } AutoReg::~AutoReg() {} } // end namespace Catch // #included from: catch_reporter_registry.hpp #define TWOBLUECUBES_CATCH_REPORTER_REGISTRY_HPP_INCLUDED #include namespace Catch { class ReporterRegistry : public IReporterRegistry { public: virtual ~ReporterRegistry() CATCH_OVERRIDE {} virtual IStreamingReporter* create( std::string const& name, Ptr const& config ) const CATCH_OVERRIDE { FactoryMap::const_iterator it = m_factories.find( name ); if( it == m_factories.end() ) return CATCH_NULL; return it->second->create( ReporterConfig( config ) ); } void registerReporter( std::string const& name, Ptr const& factory ) { m_factories.insert( std::make_pair( name, factory ) ); } void registerListener( Ptr const& factory ) { m_listeners.push_back( factory ); } virtual FactoryMap const& getFactories() const CATCH_OVERRIDE { return m_factories; } virtual Listeners const& getListeners() const CATCH_OVERRIDE { return m_listeners; } private: FactoryMap m_factories; Listeners m_listeners; }; } // #included from: catch_exception_translator_registry.hpp #define TWOBLUECUBES_CATCH_EXCEPTION_TRANSLATOR_REGISTRY_HPP_INCLUDED #ifdef __OBJC__ #import "Foundation/Foundation.h" #endif namespace Catch { class ExceptionTranslatorRegistry : public IExceptionTranslatorRegistry { public: ~ExceptionTranslatorRegistry() { deleteAll( m_translators ); } virtual void registerTranslator( const IExceptionTranslator* translator ) { m_translators.push_back( translator ); } virtual std::string translateActiveException() const { try { #ifdef __OBJC__ // In Objective-C try objective-c exceptions first @try { return tryTranslators(); } @catch (NSException *exception) { return Catch::toString( [exception description] ); } #else return tryTranslators(); #endif } catch( TestFailureException& ) { throw; } catch( std::exception& ex ) { return ex.what(); } catch( std::string& msg ) { return msg; } catch( const char* msg ) { return msg; } catch(...) { return "Unknown exception"; } } std::string tryTranslators() const { if( m_translators.empty() ) throw; else return m_translators[0]->translate( m_translators.begin()+1, m_translators.end() ); } private: std::vector m_translators; }; } // #included from: catch_tag_alias_registry.h #define TWOBLUECUBES_CATCH_TAG_ALIAS_REGISTRY_H_INCLUDED #include namespace Catch { class TagAliasRegistry : public ITagAliasRegistry { public: virtual ~TagAliasRegistry(); virtual Option find( std::string const& alias ) const; virtual std::string expandAliases( std::string const& unexpandedTestSpec ) const; void add( std::string const& alias, std::string const& tag, SourceLineInfo const& lineInfo ); private: std::map m_registry; }; } // end namespace Catch namespace Catch { namespace { class RegistryHub : public IRegistryHub, public IMutableRegistryHub { RegistryHub( RegistryHub const& ); void operator=( RegistryHub const& ); public: // IRegistryHub RegistryHub() { } virtual IReporterRegistry const& getReporterRegistry() const CATCH_OVERRIDE { return m_reporterRegistry; } virtual ITestCaseRegistry const& getTestCaseRegistry() const CATCH_OVERRIDE { return m_testCaseRegistry; } virtual IExceptionTranslatorRegistry& getExceptionTranslatorRegistry() CATCH_OVERRIDE { return m_exceptionTranslatorRegistry; } virtual ITagAliasRegistry const& getTagAliasRegistry() const CATCH_OVERRIDE { return m_tagAliasRegistry; } public: // IMutableRegistryHub virtual void registerReporter( std::string const& name, Ptr const& factory ) CATCH_OVERRIDE { m_reporterRegistry.registerReporter( name, factory ); } virtual void registerListener( Ptr const& factory ) CATCH_OVERRIDE { m_reporterRegistry.registerListener( factory ); } virtual void registerTest( TestCase const& testInfo ) CATCH_OVERRIDE { m_testCaseRegistry.registerTest( testInfo ); } virtual void registerTranslator( const IExceptionTranslator* translator ) CATCH_OVERRIDE { m_exceptionTranslatorRegistry.registerTranslator( translator ); } virtual void registerTagAlias( std::string const& alias, std::string const& tag, SourceLineInfo const& lineInfo ) CATCH_OVERRIDE { m_tagAliasRegistry.add( alias, tag, lineInfo ); } private: TestRegistry m_testCaseRegistry; ReporterRegistry m_reporterRegistry; ExceptionTranslatorRegistry m_exceptionTranslatorRegistry; TagAliasRegistry m_tagAliasRegistry; }; // Single, global, instance inline RegistryHub*& getTheRegistryHub() { static RegistryHub* theRegistryHub = CATCH_NULL; if( !theRegistryHub ) theRegistryHub = new RegistryHub(); return theRegistryHub; } } IRegistryHub& getRegistryHub() { return *getTheRegistryHub(); } IMutableRegistryHub& getMutableRegistryHub() { return *getTheRegistryHub(); } void cleanUp() { delete getTheRegistryHub(); getTheRegistryHub() = CATCH_NULL; cleanUpContext(); } std::string translateActiveException() { return getRegistryHub().getExceptionTranslatorRegistry().translateActiveException(); } } // end namespace Catch // #included from: catch_notimplemented_exception.hpp #define TWOBLUECUBES_CATCH_NOTIMPLEMENTED_EXCEPTION_HPP_INCLUDED #include namespace Catch { NotImplementedException::NotImplementedException( SourceLineInfo const& lineInfo ) : m_lineInfo( lineInfo ) { std::ostringstream oss; oss << lineInfo << ": function "; oss << "not implemented"; m_what = oss.str(); } const char* NotImplementedException::what() const CATCH_NOEXCEPT { return m_what.c_str(); } } // end namespace Catch // #included from: catch_context_impl.hpp #define TWOBLUECUBES_CATCH_CONTEXT_IMPL_HPP_INCLUDED // #included from: catch_stream.hpp #define TWOBLUECUBES_CATCH_STREAM_HPP_INCLUDED #include #include #include namespace Catch { template class StreamBufImpl : public StreamBufBase { char data[bufferSize]; WriterF m_writer; public: StreamBufImpl() { setp( data, data + sizeof(data) ); } ~StreamBufImpl() CATCH_NOEXCEPT { sync(); } private: int overflow( int c ) { sync(); if( c != EOF ) { if( pbase() == epptr() ) m_writer( std::string( 1, static_cast( c ) ) ); else sputc( static_cast( c ) ); } return 0; } int sync() { if( pbase() != pptr() ) { m_writer( std::string( pbase(), static_cast( pptr() - pbase() ) ) ); setp( pbase(), epptr() ); } return 0; } }; /////////////////////////////////////////////////////////////////////////// FileStream::FileStream( std::string const& filename ) { m_ofs.open( filename.c_str() ); if( m_ofs.fail() ) { std::ostringstream oss; oss << "Unable to open file: '" << filename << '\''; throw std::domain_error( oss.str() ); } } std::ostream& FileStream::stream() const { return m_ofs; } struct OutputDebugWriter { void operator()( std::string const&str ) { writeToDebugConsole( str ); } }; DebugOutStream::DebugOutStream() : m_streamBuf( new StreamBufImpl() ), m_os( m_streamBuf.get() ) {} std::ostream& DebugOutStream::stream() const { return m_os; } // Store the streambuf from cout up-front because // cout may get redirected when running tests CoutStream::CoutStream() : m_os( Catch::cout().rdbuf() ) {} std::ostream& CoutStream::stream() const { return m_os; } #ifndef CATCH_CONFIG_NOSTDOUT // If you #define this you must implement these functions std::ostream& cout() { return std::cout; } std::ostream& cerr() { return std::cerr; } std::ostream& clog() { return std::clog; } #endif } namespace Catch { class Context : public IMutableContext { Context() : m_config( CATCH_NULL ), m_runner( CATCH_NULL ), m_resultCapture( CATCH_NULL ) {} Context( Context const& ); void operator=( Context const& ); public: virtual ~Context() { deleteAllValues( m_generatorsByTestName ); } public: // IContext virtual IResultCapture* getResultCapture() { return m_resultCapture; } virtual IRunner* getRunner() { return m_runner; } virtual size_t getGeneratorIndex( std::string const& fileInfo, size_t totalSize ) { return getGeneratorsForCurrentTest() .getGeneratorInfo( fileInfo, totalSize ) .getCurrentIndex(); } virtual bool advanceGeneratorsForCurrentTest() { IGeneratorsForTest* generators = findGeneratorsForCurrentTest(); return generators && generators->moveNext(); } virtual Ptr getConfig() const { return m_config; } public: // IMutableContext virtual void setResultCapture( IResultCapture* resultCapture ) { m_resultCapture = resultCapture; } virtual void setRunner( IRunner* runner ) { m_runner = runner; } virtual void setConfig( Ptr const& config ) { m_config = config; } friend IMutableContext& getCurrentMutableContext(); private: IGeneratorsForTest* findGeneratorsForCurrentTest() { std::string testName = getResultCapture()->getCurrentTestName(); std::map::const_iterator it = m_generatorsByTestName.find( testName ); return it != m_generatorsByTestName.end() ? it->second : CATCH_NULL; } IGeneratorsForTest& getGeneratorsForCurrentTest() { IGeneratorsForTest* generators = findGeneratorsForCurrentTest(); if( !generators ) { std::string testName = getResultCapture()->getCurrentTestName(); generators = createGeneratorsForTest(); m_generatorsByTestName.insert( std::make_pair( testName, generators ) ); } return *generators; } private: Ptr m_config; IRunner* m_runner; IResultCapture* m_resultCapture; std::map m_generatorsByTestName; }; namespace { Context* currentContext = CATCH_NULL; } IMutableContext& getCurrentMutableContext() { if( !currentContext ) currentContext = new Context(); return *currentContext; } IContext& getCurrentContext() { return getCurrentMutableContext(); } void cleanUpContext() { delete currentContext; currentContext = CATCH_NULL; } } // #included from: catch_console_colour_impl.hpp #define TWOBLUECUBES_CATCH_CONSOLE_COLOUR_IMPL_HPP_INCLUDED // #included from: catch_errno_guard.hpp #define TWOBLUECUBES_CATCH_ERRNO_GUARD_HPP_INCLUDED #include namespace Catch { class ErrnoGuard { public: ErrnoGuard():m_oldErrno(errno){} ~ErrnoGuard() { errno = m_oldErrno; } private: int m_oldErrno; }; } namespace Catch { namespace { struct IColourImpl { virtual ~IColourImpl() {} virtual void use( Colour::Code _colourCode ) = 0; }; struct NoColourImpl : IColourImpl { void use( Colour::Code ) {} static IColourImpl* instance() { static NoColourImpl s_instance; return &s_instance; } }; } // anon namespace } // namespace Catch #if !defined( CATCH_CONFIG_COLOUR_NONE ) && !defined( CATCH_CONFIG_COLOUR_WINDOWS ) && !defined( CATCH_CONFIG_COLOUR_ANSI ) # ifdef CATCH_PLATFORM_WINDOWS # define CATCH_CONFIG_COLOUR_WINDOWS # else # define CATCH_CONFIG_COLOUR_ANSI # endif #endif #if defined ( CATCH_CONFIG_COLOUR_WINDOWS ) ///////////////////////////////////////// namespace Catch { namespace { class Win32ColourImpl : public IColourImpl { public: Win32ColourImpl() : stdoutHandle( GetStdHandle(STD_OUTPUT_HANDLE) ) { CONSOLE_SCREEN_BUFFER_INFO csbiInfo; GetConsoleScreenBufferInfo( stdoutHandle, &csbiInfo ); originalForegroundAttributes = csbiInfo.wAttributes & ~( BACKGROUND_GREEN | BACKGROUND_RED | BACKGROUND_BLUE | BACKGROUND_INTENSITY ); originalBackgroundAttributes = csbiInfo.wAttributes & ~( FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_BLUE | FOREGROUND_INTENSITY ); } virtual void use( Colour::Code _colourCode ) { switch( _colourCode ) { case Colour::None: return setTextAttribute( originalForegroundAttributes ); case Colour::White: return setTextAttribute( FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_BLUE ); case Colour::Red: return setTextAttribute( FOREGROUND_RED ); case Colour::Green: return setTextAttribute( FOREGROUND_GREEN ); case Colour::Blue: return setTextAttribute( FOREGROUND_BLUE ); case Colour::Cyan: return setTextAttribute( FOREGROUND_BLUE | FOREGROUND_GREEN ); case Colour::Yellow: return setTextAttribute( FOREGROUND_RED | FOREGROUND_GREEN ); case Colour::Grey: return setTextAttribute( 0 ); case Colour::LightGrey: return setTextAttribute( FOREGROUND_INTENSITY ); case Colour::BrightRed: return setTextAttribute( FOREGROUND_INTENSITY | FOREGROUND_RED ); case Colour::BrightGreen: return setTextAttribute( FOREGROUND_INTENSITY | FOREGROUND_GREEN ); case Colour::BrightWhite: return setTextAttribute( FOREGROUND_INTENSITY | FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_BLUE ); case Colour::Bright: throw std::logic_error( "not a colour" ); } } private: void setTextAttribute( WORD _textAttribute ) { SetConsoleTextAttribute( stdoutHandle, _textAttribute | originalBackgroundAttributes ); } HANDLE stdoutHandle; WORD originalForegroundAttributes; WORD originalBackgroundAttributes; }; IColourImpl* platformColourInstance() { static Win32ColourImpl s_instance; Ptr config = getCurrentContext().getConfig(); UseColour::YesOrNo colourMode = config ? config->useColour() : UseColour::Auto; if( colourMode == UseColour::Auto ) colourMode = !isDebuggerActive() ? UseColour::Yes : UseColour::No; return colourMode == UseColour::Yes ? &s_instance : NoColourImpl::instance(); } } // end anon namespace } // end namespace Catch #elif defined( CATCH_CONFIG_COLOUR_ANSI ) ////////////////////////////////////// #include namespace Catch { namespace { // use POSIX/ ANSI console terminal codes // Thanks to Adam Strzelecki for original contribution // (http://github.com/nanoant) // https://github.com/philsquared/Catch/pull/131 class PosixColourImpl : public IColourImpl { public: virtual void use( Colour::Code _colourCode ) { switch( _colourCode ) { case Colour::None: case Colour::White: return setColour( "[0m" ); case Colour::Red: return setColour( "[0;31m" ); case Colour::Green: return setColour( "[0;32m" ); case Colour::Blue: return setColour( "[0;34m" ); case Colour::Cyan: return setColour( "[0;36m" ); case Colour::Yellow: return setColour( "[0;33m" ); case Colour::Grey: return setColour( "[1;30m" ); case Colour::LightGrey: return setColour( "[0;37m" ); case Colour::BrightRed: return setColour( "[1;31m" ); case Colour::BrightGreen: return setColour( "[1;32m" ); case Colour::BrightWhite: return setColour( "[1;37m" ); case Colour::Bright: throw std::logic_error( "not a colour" ); } } static IColourImpl* instance() { static PosixColourImpl s_instance; return &s_instance; } private: void setColour( const char* _escapeCode ) { Catch::cout() << '\033' << _escapeCode; } }; IColourImpl* platformColourInstance() { ErrnoGuard guard; Ptr config = getCurrentContext().getConfig(); UseColour::YesOrNo colourMode = config ? config->useColour() : UseColour::Auto; if( colourMode == UseColour::Auto ) colourMode = (!isDebuggerActive() && isatty(STDOUT_FILENO) ) ? UseColour::Yes : UseColour::No; return colourMode == UseColour::Yes ? PosixColourImpl::instance() : NoColourImpl::instance(); } } // end anon namespace } // end namespace Catch #else // not Windows or ANSI /////////////////////////////////////////////// namespace Catch { static IColourImpl* platformColourInstance() { return NoColourImpl::instance(); } } // end namespace Catch #endif // Windows/ ANSI/ None namespace Catch { Colour::Colour( Code _colourCode ) : m_moved( false ) { use( _colourCode ); } Colour::Colour( Colour const& _other ) : m_moved( false ) { const_cast( _other ).m_moved = true; } Colour::~Colour(){ if( !m_moved ) use( None ); } void Colour::use( Code _colourCode ) { static IColourImpl* impl = platformColourInstance(); impl->use( _colourCode ); } } // end namespace Catch // #included from: catch_generators_impl.hpp #define TWOBLUECUBES_CATCH_GENERATORS_IMPL_HPP_INCLUDED #include #include #include namespace Catch { struct GeneratorInfo : IGeneratorInfo { GeneratorInfo( std::size_t size ) : m_size( size ), m_currentIndex( 0 ) {} bool moveNext() { if( ++m_currentIndex == m_size ) { m_currentIndex = 0; return false; } return true; } std::size_t getCurrentIndex() const { return m_currentIndex; } std::size_t m_size; std::size_t m_currentIndex; }; /////////////////////////////////////////////////////////////////////////// class GeneratorsForTest : public IGeneratorsForTest { public: ~GeneratorsForTest() { deleteAll( m_generatorsInOrder ); } IGeneratorInfo& getGeneratorInfo( std::string const& fileInfo, std::size_t size ) { std::map::const_iterator it = m_generatorsByName.find( fileInfo ); if( it == m_generatorsByName.end() ) { IGeneratorInfo* info = new GeneratorInfo( size ); m_generatorsByName.insert( std::make_pair( fileInfo, info ) ); m_generatorsInOrder.push_back( info ); return *info; } return *it->second; } bool moveNext() { std::vector::const_iterator it = m_generatorsInOrder.begin(); std::vector::const_iterator itEnd = m_generatorsInOrder.end(); for(; it != itEnd; ++it ) { if( (*it)->moveNext() ) return true; } return false; } private: std::map m_generatorsByName; std::vector m_generatorsInOrder; }; IGeneratorsForTest* createGeneratorsForTest() { return new GeneratorsForTest(); } } // end namespace Catch // #included from: catch_assertionresult.hpp #define TWOBLUECUBES_CATCH_ASSERTIONRESULT_HPP_INCLUDED namespace Catch { AssertionInfo::AssertionInfo():macroName(""), capturedExpression(""), resultDisposition(ResultDisposition::Normal), secondArg(""){} AssertionInfo::AssertionInfo( char const * _macroName, SourceLineInfo const& _lineInfo, char const * _capturedExpression, ResultDisposition::Flags _resultDisposition, char const * _secondArg) : macroName( _macroName ), lineInfo( _lineInfo ), capturedExpression( _capturedExpression ), resultDisposition( _resultDisposition ), secondArg( _secondArg ) {} AssertionResult::AssertionResult() {} AssertionResult::AssertionResult( AssertionInfo const& info, AssertionResultData const& data ) : m_info( info ), m_resultData( data ) {} AssertionResult::~AssertionResult() {} // Result was a success bool AssertionResult::succeeded() const { return Catch::isOk( m_resultData.resultType ); } // Result was a success, or failure is suppressed bool AssertionResult::isOk() const { return Catch::isOk( m_resultData.resultType ) || shouldSuppressFailure( m_info.resultDisposition ); } ResultWas::OfType AssertionResult::getResultType() const { return m_resultData.resultType; } bool AssertionResult::hasExpression() const { return m_info.capturedExpression[0] != 0; } bool AssertionResult::hasMessage() const { return !m_resultData.message.empty(); } std::string capturedExpressionWithSecondArgument( char const * capturedExpression, char const * secondArg ) { return (secondArg[0] == 0 || secondArg[0] == '"' && secondArg[1] == '"') ? capturedExpression : std::string(capturedExpression) + ", " + secondArg; } std::string AssertionResult::getExpression() const { if( isFalseTest( m_info.resultDisposition ) ) return "!(" + capturedExpressionWithSecondArgument(m_info.capturedExpression, m_info.secondArg) + ")"; else return capturedExpressionWithSecondArgument(m_info.capturedExpression, m_info.secondArg); } std::string AssertionResult::getExpressionInMacro() const { if( m_info.macroName[0] == 0 ) return capturedExpressionWithSecondArgument(m_info.capturedExpression, m_info.secondArg); else return std::string(m_info.macroName) + "( " + capturedExpressionWithSecondArgument(m_info.capturedExpression, m_info.secondArg) + " )"; } bool AssertionResult::hasExpandedExpression() const { return hasExpression() && getExpandedExpression() != getExpression(); } std::string AssertionResult::getExpandedExpression() const { return m_resultData.reconstructExpression(); } std::string AssertionResult::getMessage() const { return m_resultData.message; } SourceLineInfo AssertionResult::getSourceInfo() const { return m_info.lineInfo; } std::string AssertionResult::getTestMacroName() const { return m_info.macroName; } void AssertionResult::discardDecomposedExpression() const { m_resultData.decomposedExpression = CATCH_NULL; } void AssertionResult::expandDecomposedExpression() const { m_resultData.reconstructExpression(); } } // end namespace Catch // #included from: catch_test_case_info.hpp #define TWOBLUECUBES_CATCH_TEST_CASE_INFO_HPP_INCLUDED #include namespace Catch { inline TestCaseInfo::SpecialProperties parseSpecialTag( std::string const& tag ) { if( startsWith( tag, '.' ) || tag == "hide" || tag == "!hide" ) return TestCaseInfo::IsHidden; else if( tag == "!throws" ) return TestCaseInfo::Throws; else if( tag == "!shouldfail" ) return TestCaseInfo::ShouldFail; else if( tag == "!mayfail" ) return TestCaseInfo::MayFail; else if( tag == "!nonportable" ) return TestCaseInfo::NonPortable; else return TestCaseInfo::None; } inline bool isReservedTag( std::string const& tag ) { return parseSpecialTag( tag ) == TestCaseInfo::None && tag.size() > 0 && !std::isalnum( tag[0] ); } inline void enforceNotReservedTag( std::string const& tag, SourceLineInfo const& _lineInfo ) { if( isReservedTag( tag ) ) { std::ostringstream ss; ss << Colour(Colour::Red) << "Tag name [" << tag << "] not allowed.\n" << "Tag names starting with non alpha-numeric characters are reserved\n" << Colour(Colour::FileName) << _lineInfo << '\n'; throw std::runtime_error(ss.str()); } } TestCase makeTestCase( ITestCase* _testCase, std::string const& _className, std::string const& _name, std::string const& _descOrTags, SourceLineInfo const& _lineInfo ) { bool isHidden( startsWith( _name, "./" ) ); // Legacy support // Parse out tags std::set tags; std::string desc, tag; bool inTag = false; for( std::size_t i = 0; i < _descOrTags.size(); ++i ) { char c = _descOrTags[i]; if( !inTag ) { if( c == '[' ) inTag = true; else desc += c; } else { if( c == ']' ) { TestCaseInfo::SpecialProperties prop = parseSpecialTag( tag ); if( prop == TestCaseInfo::IsHidden ) isHidden = true; else if( prop == TestCaseInfo::None ) enforceNotReservedTag( tag, _lineInfo ); tags.insert( tag ); tag.clear(); inTag = false; } else tag += c; } } if( isHidden ) { tags.insert( "hide" ); tags.insert( "." ); } TestCaseInfo info( _name, _className, desc, tags, _lineInfo ); return TestCase( _testCase, info ); } void setTags( TestCaseInfo& testCaseInfo, std::set const& tags ) { testCaseInfo.tags = tags; testCaseInfo.lcaseTags.clear(); std::ostringstream oss; for( std::set::const_iterator it = tags.begin(), itEnd = tags.end(); it != itEnd; ++it ) { oss << '[' << *it << ']'; std::string lcaseTag = toLower( *it ); testCaseInfo.properties = static_cast( testCaseInfo.properties | parseSpecialTag( lcaseTag ) ); testCaseInfo.lcaseTags.insert( lcaseTag ); } testCaseInfo.tagsAsString = oss.str(); } TestCaseInfo::TestCaseInfo( std::string const& _name, std::string const& _className, std::string const& _description, std::set const& _tags, SourceLineInfo const& _lineInfo ) : name( _name ), className( _className ), description( _description ), lineInfo( _lineInfo ), properties( None ) { setTags( *this, _tags ); } TestCaseInfo::TestCaseInfo( TestCaseInfo const& other ) : name( other.name ), className( other.className ), description( other.description ), tags( other.tags ), lcaseTags( other.lcaseTags ), tagsAsString( other.tagsAsString ), lineInfo( other.lineInfo ), properties( other.properties ) {} bool TestCaseInfo::isHidden() const { return ( properties & IsHidden ) != 0; } bool TestCaseInfo::throws() const { return ( properties & Throws ) != 0; } bool TestCaseInfo::okToFail() const { return ( properties & (ShouldFail | MayFail ) ) != 0; } bool TestCaseInfo::expectedToFail() const { return ( properties & (ShouldFail ) ) != 0; } TestCase::TestCase( ITestCase* testCase, TestCaseInfo const& info ) : TestCaseInfo( info ), test( testCase ) {} TestCase::TestCase( TestCase const& other ) : TestCaseInfo( other ), test( other.test ) {} TestCase TestCase::withName( std::string const& _newName ) const { TestCase other( *this ); other.name = _newName; return other; } void TestCase::swap( TestCase& other ) { test.swap( other.test ); name.swap( other.name ); className.swap( other.className ); description.swap( other.description ); tags.swap( other.tags ); lcaseTags.swap( other.lcaseTags ); tagsAsString.swap( other.tagsAsString ); std::swap( TestCaseInfo::properties, static_cast( other ).properties ); std::swap( lineInfo, other.lineInfo ); } void TestCase::invoke() const { test->invoke(); } bool TestCase::operator == ( TestCase const& other ) const { return test.get() == other.test.get() && name == other.name && className == other.className; } bool TestCase::operator < ( TestCase const& other ) const { return name < other.name; } TestCase& TestCase::operator = ( TestCase const& other ) { TestCase temp( other ); swap( temp ); return *this; } TestCaseInfo const& TestCase::getTestCaseInfo() const { return *this; } } // end namespace Catch // #included from: catch_version.hpp #define TWOBLUECUBES_CATCH_VERSION_HPP_INCLUDED namespace Catch { Version::Version ( unsigned int _majorVersion, unsigned int _minorVersion, unsigned int _patchNumber, char const * const _branchName, unsigned int _buildNumber ) : majorVersion( _majorVersion ), minorVersion( _minorVersion ), patchNumber( _patchNumber ), branchName( _branchName ), buildNumber( _buildNumber ) {} std::ostream& operator << ( std::ostream& os, Version const& version ) { os << version.majorVersion << '.' << version.minorVersion << '.' << version.patchNumber; // branchName is never null -> 0th char is \0 if it is empty if (version.branchName[0]) { os << '-' << version.branchName << '.' << version.buildNumber; } return os; } inline Version libraryVersion() { static Version version( 1, 12, 1, "", 0 ); return version; } } // #included from: catch_message.hpp #define TWOBLUECUBES_CATCH_MESSAGE_HPP_INCLUDED namespace Catch { MessageInfo::MessageInfo( std::string const& _macroName, SourceLineInfo const& _lineInfo, ResultWas::OfType _type ) : macroName( _macroName ), lineInfo( _lineInfo ), type( _type ), sequence( ++globalCount ) {} // This may need protecting if threading support is added unsigned int MessageInfo::globalCount = 0; //////////////////////////////////////////////////////////////////////////// ScopedMessage::ScopedMessage( MessageBuilder const& builder ) : m_info( builder.m_info ) { m_info.message = builder.m_stream.str(); getResultCapture().pushScopedMessage( m_info ); } ScopedMessage::ScopedMessage( ScopedMessage const& other ) : m_info( other.m_info ) {} #if defined(_MSC_VER) #pragma warning(push) #pragma warning(disable:4996) // std::uncaught_exception is deprecated in C++17 #endif ScopedMessage::~ScopedMessage() { if ( !std::uncaught_exception() ){ getResultCapture().popScopedMessage(m_info); } } #if defined(_MSC_VER) #pragma warning(pop) #endif } // end namespace Catch // #included from: catch_legacy_reporter_adapter.hpp #define TWOBLUECUBES_CATCH_LEGACY_REPORTER_ADAPTER_HPP_INCLUDED // #included from: catch_legacy_reporter_adapter.h #define TWOBLUECUBES_CATCH_LEGACY_REPORTER_ADAPTER_H_INCLUDED namespace Catch { // Deprecated struct IReporter : IShared { virtual ~IReporter(); virtual bool shouldRedirectStdout() const = 0; virtual void StartTesting() = 0; virtual void EndTesting( Totals const& totals ) = 0; virtual void StartGroup( std::string const& groupName ) = 0; virtual void EndGroup( std::string const& groupName, Totals const& totals ) = 0; virtual void StartTestCase( TestCaseInfo const& testInfo ) = 0; virtual void EndTestCase( TestCaseInfo const& testInfo, Totals const& totals, std::string const& stdOut, std::string const& stdErr ) = 0; virtual void StartSection( std::string const& sectionName, std::string const& description ) = 0; virtual void EndSection( std::string const& sectionName, Counts const& assertions ) = 0; virtual void NoAssertionsInSection( std::string const& sectionName ) = 0; virtual void NoAssertionsInTestCase( std::string const& testName ) = 0; virtual void Aborted() = 0; virtual void Result( AssertionResult const& result ) = 0; }; class LegacyReporterAdapter : public SharedImpl { public: LegacyReporterAdapter( Ptr const& legacyReporter ); virtual ~LegacyReporterAdapter(); virtual ReporterPreferences getPreferences() const; virtual void noMatchingTestCases( std::string const& ); virtual void testRunStarting( TestRunInfo const& ); virtual void testGroupStarting( GroupInfo const& groupInfo ); virtual void testCaseStarting( TestCaseInfo const& testInfo ); virtual void sectionStarting( SectionInfo const& sectionInfo ); virtual void assertionStarting( AssertionInfo const& ); virtual bool assertionEnded( AssertionStats const& assertionStats ); virtual void sectionEnded( SectionStats const& sectionStats ); virtual void testCaseEnded( TestCaseStats const& testCaseStats ); virtual void testGroupEnded( TestGroupStats const& testGroupStats ); virtual void testRunEnded( TestRunStats const& testRunStats ); virtual void skipTest( TestCaseInfo const& ); private: Ptr m_legacyReporter; }; } namespace Catch { LegacyReporterAdapter::LegacyReporterAdapter( Ptr const& legacyReporter ) : m_legacyReporter( legacyReporter ) {} LegacyReporterAdapter::~LegacyReporterAdapter() {} ReporterPreferences LegacyReporterAdapter::getPreferences() const { ReporterPreferences prefs; prefs.shouldRedirectStdOut = m_legacyReporter->shouldRedirectStdout(); return prefs; } void LegacyReporterAdapter::noMatchingTestCases( std::string const& ) {} void LegacyReporterAdapter::testRunStarting( TestRunInfo const& ) { m_legacyReporter->StartTesting(); } void LegacyReporterAdapter::testGroupStarting( GroupInfo const& groupInfo ) { m_legacyReporter->StartGroup( groupInfo.name ); } void LegacyReporterAdapter::testCaseStarting( TestCaseInfo const& testInfo ) { m_legacyReporter->StartTestCase( testInfo ); } void LegacyReporterAdapter::sectionStarting( SectionInfo const& sectionInfo ) { m_legacyReporter->StartSection( sectionInfo.name, sectionInfo.description ); } void LegacyReporterAdapter::assertionStarting( AssertionInfo const& ) { // Not on legacy interface } bool LegacyReporterAdapter::assertionEnded( AssertionStats const& assertionStats ) { if( assertionStats.assertionResult.getResultType() != ResultWas::Ok ) { for( std::vector::const_iterator it = assertionStats.infoMessages.begin(), itEnd = assertionStats.infoMessages.end(); it != itEnd; ++it ) { if( it->type == ResultWas::Info ) { ResultBuilder rb( it->macroName.c_str(), it->lineInfo, "", ResultDisposition::Normal ); rb << it->message; rb.setResultType( ResultWas::Info ); AssertionResult result = rb.build(); m_legacyReporter->Result( result ); } } } m_legacyReporter->Result( assertionStats.assertionResult ); return true; } void LegacyReporterAdapter::sectionEnded( SectionStats const& sectionStats ) { if( sectionStats.missingAssertions ) m_legacyReporter->NoAssertionsInSection( sectionStats.sectionInfo.name ); m_legacyReporter->EndSection( sectionStats.sectionInfo.name, sectionStats.assertions ); } void LegacyReporterAdapter::testCaseEnded( TestCaseStats const& testCaseStats ) { m_legacyReporter->EndTestCase ( testCaseStats.testInfo, testCaseStats.totals, testCaseStats.stdOut, testCaseStats.stdErr ); } void LegacyReporterAdapter::testGroupEnded( TestGroupStats const& testGroupStats ) { if( testGroupStats.aborting ) m_legacyReporter->Aborted(); m_legacyReporter->EndGroup( testGroupStats.groupInfo.name, testGroupStats.totals ); } void LegacyReporterAdapter::testRunEnded( TestRunStats const& testRunStats ) { m_legacyReporter->EndTesting( testRunStats.totals ); } void LegacyReporterAdapter::skipTest( TestCaseInfo const& ) { } } // #included from: catch_timer.hpp #ifdef __clang__ #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wc++11-long-long" #endif #ifdef CATCH_PLATFORM_WINDOWS #else #include #endif namespace Catch { namespace { #ifdef CATCH_PLATFORM_WINDOWS UInt64 getCurrentTicks() { static UInt64 hz=0, hzo=0; if (!hz) { QueryPerformanceFrequency( reinterpret_cast( &hz ) ); QueryPerformanceCounter( reinterpret_cast( &hzo ) ); } UInt64 t; QueryPerformanceCounter( reinterpret_cast( &t ) ); return ((t-hzo)*1000000)/hz; } #else UInt64 getCurrentTicks() { timeval t; gettimeofday(&t,CATCH_NULL); return static_cast( t.tv_sec ) * 1000000ull + static_cast( t.tv_usec ); } #endif } void Timer::start() { m_ticks = getCurrentTicks(); } unsigned int Timer::getElapsedMicroseconds() const { return static_cast(getCurrentTicks() - m_ticks); } unsigned int Timer::getElapsedMilliseconds() const { return static_cast(getElapsedMicroseconds()/1000); } double Timer::getElapsedSeconds() const { return getElapsedMicroseconds()/1000000.0; } } // namespace Catch #ifdef __clang__ #pragma clang diagnostic pop #endif // #included from: catch_common.hpp #define TWOBLUECUBES_CATCH_COMMON_HPP_INCLUDED #include #include namespace Catch { bool startsWith( std::string const& s, std::string const& prefix ) { return s.size() >= prefix.size() && std::equal(prefix.begin(), prefix.end(), s.begin()); } bool startsWith( std::string const& s, char prefix ) { return !s.empty() && s[0] == prefix; } bool endsWith( std::string const& s, std::string const& suffix ) { return s.size() >= suffix.size() && std::equal(suffix.rbegin(), suffix.rend(), s.rbegin()); } bool endsWith( std::string const& s, char suffix ) { return !s.empty() && s[s.size()-1] == suffix; } bool contains( std::string const& s, std::string const& infix ) { return s.find( infix ) != std::string::npos; } char toLowerCh(char c) { return static_cast( std::tolower( c ) ); } void toLowerInPlace( std::string& s ) { std::transform( s.begin(), s.end(), s.begin(), toLowerCh ); } std::string toLower( std::string const& s ) { std::string lc = s; toLowerInPlace( lc ); return lc; } std::string trim( std::string const& str ) { static char const* whitespaceChars = "\n\r\t "; std::string::size_type start = str.find_first_not_of( whitespaceChars ); std::string::size_type end = str.find_last_not_of( whitespaceChars ); return start != std::string::npos ? str.substr( start, 1+end-start ) : std::string(); } bool replaceInPlace( std::string& str, std::string const& replaceThis, std::string const& withThis ) { bool replaced = false; std::size_t i = str.find( replaceThis ); while( i != std::string::npos ) { replaced = true; str = str.substr( 0, i ) + withThis + str.substr( i+replaceThis.size() ); if( i < str.size()-withThis.size() ) i = str.find( replaceThis, i+withThis.size() ); else i = std::string::npos; } return replaced; } pluralise::pluralise( std::size_t count, std::string const& label ) : m_count( count ), m_label( label ) {} std::ostream& operator << ( std::ostream& os, pluralise const& pluraliser ) { os << pluraliser.m_count << ' ' << pluraliser.m_label; if( pluraliser.m_count != 1 ) os << 's'; return os; } SourceLineInfo::SourceLineInfo() : file(""), line( 0 ){} SourceLineInfo::SourceLineInfo( char const* _file, std::size_t _line ) : file( _file ), line( _line ) {} bool SourceLineInfo::empty() const { return file[0] == '\0'; } bool SourceLineInfo::operator == ( SourceLineInfo const& other ) const { return line == other.line && (file == other.file || std::strcmp(file, other.file) == 0); } bool SourceLineInfo::operator < ( SourceLineInfo const& other ) const { return line < other.line || ( line == other.line && (std::strcmp(file, other.file) < 0)); } void seedRng( IConfig const& config ) { if( config.rngSeed() != 0 ) std::srand( config.rngSeed() ); } unsigned int rngSeed() { return getCurrentContext().getConfig()->rngSeed(); } std::ostream& operator << ( std::ostream& os, SourceLineInfo const& info ) { #ifndef __GNUG__ os << info.file << '(' << info.line << ')'; #else os << info.file << ':' << info.line; #endif return os; } void throwLogicError( std::string const& message, SourceLineInfo const& locationInfo ) { std::ostringstream oss; oss << locationInfo << ": Internal Catch error: '" << message << '\''; if( alwaysTrue() ) throw std::logic_error( oss.str() ); } } // #included from: catch_section.hpp #define TWOBLUECUBES_CATCH_SECTION_HPP_INCLUDED namespace Catch { SectionInfo::SectionInfo ( SourceLineInfo const& _lineInfo, std::string const& _name, std::string const& _description ) : name( _name ), description( _description ), lineInfo( _lineInfo ) {} Section::Section( SectionInfo const& info ) : m_info( info ), m_sectionIncluded( getResultCapture().sectionStarted( m_info, m_assertions ) ) { m_timer.start(); } #if defined(_MSC_VER) #pragma warning(push) #pragma warning(disable:4996) // std::uncaught_exception is deprecated in C++17 #endif Section::~Section() { if( m_sectionIncluded ) { SectionEndInfo endInfo( m_info, m_assertions, m_timer.getElapsedSeconds() ); if( std::uncaught_exception() ) getResultCapture().sectionEndedEarly( endInfo ); else getResultCapture().sectionEnded( endInfo ); } } #if defined(_MSC_VER) #pragma warning(pop) #endif // This indicates whether the section should be executed or not Section::operator bool() const { return m_sectionIncluded; } } // end namespace Catch // #included from: catch_debugger.hpp #define TWOBLUECUBES_CATCH_DEBUGGER_HPP_INCLUDED #ifdef CATCH_PLATFORM_MAC #include #include #include #include #include namespace Catch{ // The following function is taken directly from the following technical note: // http://developer.apple.com/library/mac/#qa/qa2004/qa1361.html // Returns true if the current process is being debugged (either // running under the debugger or has a debugger attached post facto). bool isDebuggerActive(){ int mib[4]; struct kinfo_proc info; size_t size; // Initialize the flags so that, if sysctl fails for some bizarre // reason, we get a predictable result. info.kp_proc.p_flag = 0; // Initialize mib, which tells sysctl the info we want, in this case // we're looking for information about a specific process ID. mib[0] = CTL_KERN; mib[1] = KERN_PROC; mib[2] = KERN_PROC_PID; mib[3] = getpid(); // Call sysctl. size = sizeof(info); if( sysctl(mib, sizeof(mib) / sizeof(*mib), &info, &size, CATCH_NULL, 0) != 0 ) { Catch::cerr() << "\n** Call to sysctl failed - unable to determine if debugger is active **\n" << std::endl; return false; } // We're being debugged if the P_TRACED flag is set. return ( (info.kp_proc.p_flag & P_TRACED) != 0 ); } } // namespace Catch #elif defined(CATCH_PLATFORM_LINUX) #include #include namespace Catch{ // The standard POSIX way of detecting a debugger is to attempt to // ptrace() the process, but this needs to be done from a child and not // this process itself to still allow attaching to this process later // if wanted, so is rather heavy. Under Linux we have the PID of the // "debugger" (which doesn't need to be gdb, of course, it could also // be strace, for example) in /proc/$PID/status, so just get it from // there instead. bool isDebuggerActive(){ // Libstdc++ has a bug, where std::ifstream sets errno to 0 // This way our users can properly assert over errno values ErrnoGuard guard; std::ifstream in("/proc/self/status"); for( std::string line; std::getline(in, line); ) { static const int PREFIX_LEN = 11; if( line.compare(0, PREFIX_LEN, "TracerPid:\t") == 0 ) { // We're traced if the PID is not 0 and no other PID starts // with 0 digit, so it's enough to check for just a single // character. return line.length() > PREFIX_LEN && line[PREFIX_LEN] != '0'; } } return false; } } // namespace Catch #elif defined(_MSC_VER) extern "C" __declspec(dllimport) int __stdcall IsDebuggerPresent(); namespace Catch { bool isDebuggerActive() { return IsDebuggerPresent() != 0; } } #elif defined(__MINGW32__) extern "C" __declspec(dllimport) int __stdcall IsDebuggerPresent(); namespace Catch { bool isDebuggerActive() { return IsDebuggerPresent() != 0; } } #else namespace Catch { inline bool isDebuggerActive() { return false; } } #endif // Platform #ifdef CATCH_PLATFORM_WINDOWS namespace Catch { void writeToDebugConsole( std::string const& text ) { ::OutputDebugStringA( text.c_str() ); } } #else namespace Catch { void writeToDebugConsole( std::string const& text ) { // !TBD: Need a version for Mac/ XCode and other IDEs Catch::cout() << text; } } #endif // Platform // #included from: catch_tostring.hpp #define TWOBLUECUBES_CATCH_TOSTRING_HPP_INCLUDED namespace Catch { namespace Detail { const std::string unprintableString = "{?}"; namespace { const int hexThreshold = 255; struct Endianness { enum Arch { Big, Little }; static Arch which() { union _{ int asInt; char asChar[sizeof (int)]; } u; u.asInt = 1; return ( u.asChar[sizeof(int)-1] == 1 ) ? Big : Little; } }; } std::string rawMemoryToString( const void *object, std::size_t size ) { // Reverse order for little endian architectures int i = 0, end = static_cast( size ), inc = 1; if( Endianness::which() == Endianness::Little ) { i = end-1; end = inc = -1; } unsigned char const *bytes = static_cast(object); std::ostringstream os; os << "0x" << std::setfill('0') << std::hex; for( ; i != end; i += inc ) os << std::setw(2) << static_cast(bytes[i]); return os.str(); } } std::string toString( std::string const& value ) { std::string s = value; if( getCurrentContext().getConfig()->showInvisibles() ) { for(size_t i = 0; i < s.size(); ++i ) { std::string subs; switch( s[i] ) { case '\n': subs = "\\n"; break; case '\t': subs = "\\t"; break; default: break; } if( !subs.empty() ) { s = s.substr( 0, i ) + subs + s.substr( i+1 ); ++i; } } } return '"' + s + '"'; } std::string toString( std::wstring const& value ) { std::string s; s.reserve( value.size() ); for(size_t i = 0; i < value.size(); ++i ) s += value[i] <= 0xff ? static_cast( value[i] ) : '?'; return Catch::toString( s ); } std::string toString( const char* const value ) { return value ? Catch::toString( std::string( value ) ) : std::string( "{null string}" ); } std::string toString( char* const value ) { return Catch::toString( static_cast( value ) ); } std::string toString( const wchar_t* const value ) { return value ? Catch::toString( std::wstring(value) ) : std::string( "{null string}" ); } std::string toString( wchar_t* const value ) { return Catch::toString( static_cast( value ) ); } std::string toString( int value ) { std::ostringstream oss; oss << value; if( value > Detail::hexThreshold ) oss << " (0x" << std::hex << value << ')'; return oss.str(); } std::string toString( unsigned long value ) { std::ostringstream oss; oss << value; if( value > Detail::hexThreshold ) oss << " (0x" << std::hex << value << ')'; return oss.str(); } std::string toString( unsigned int value ) { return Catch::toString( static_cast( value ) ); } template std::string fpToString( T value, int precision ) { std::ostringstream oss; oss << std::setprecision( precision ) << std::fixed << value; std::string d = oss.str(); std::size_t i = d.find_last_not_of( '0' ); if( i != std::string::npos && i != d.size()-1 ) { if( d[i] == '.' ) i++; d = d.substr( 0, i+1 ); } return d; } std::string toString( const double value ) { return fpToString( value, 10 ); } std::string toString( const float value ) { return fpToString( value, 5 ) + 'f'; } std::string toString( bool value ) { return value ? "true" : "false"; } std::string toString( char value ) { if ( value == '\r' ) return "'\\r'"; if ( value == '\f' ) return "'\\f'"; if ( value == '\n' ) return "'\\n'"; if ( value == '\t' ) return "'\\t'"; if ( '\0' <= value && value < ' ' ) return toString( static_cast( value ) ); char chstr[] = "' '"; chstr[1] = value; return chstr; } std::string toString( signed char value ) { return toString( static_cast( value ) ); } std::string toString( unsigned char value ) { return toString( static_cast( value ) ); } #ifdef CATCH_CONFIG_CPP11_LONG_LONG std::string toString( long long value ) { std::ostringstream oss; oss << value; if( value > Detail::hexThreshold ) oss << " (0x" << std::hex << value << ')'; return oss.str(); } std::string toString( unsigned long long value ) { std::ostringstream oss; oss << value; if( value > Detail::hexThreshold ) oss << " (0x" << std::hex << value << ')'; return oss.str(); } #endif #ifdef CATCH_CONFIG_CPP11_NULLPTR std::string toString( std::nullptr_t ) { return "nullptr"; } #endif #ifdef __OBJC__ std::string toString( NSString const * const& nsstring ) { if( !nsstring ) return "nil"; return "@" + toString([nsstring UTF8String]); } std::string toString( NSString * CATCH_ARC_STRONG & nsstring ) { if( !nsstring ) return "nil"; return "@" + toString([nsstring UTF8String]); } std::string toString( NSObject* const& nsObject ) { return toString( [nsObject description] ); } #endif } // end namespace Catch // #included from: catch_result_builder.hpp #define TWOBLUECUBES_CATCH_RESULT_BUILDER_HPP_INCLUDED namespace Catch { ResultBuilder::ResultBuilder( char const* macroName, SourceLineInfo const& lineInfo, char const* capturedExpression, ResultDisposition::Flags resultDisposition, char const* secondArg ) : m_assertionInfo( macroName, lineInfo, capturedExpression, resultDisposition, secondArg ), m_shouldDebugBreak( false ), m_shouldThrow( false ), m_guardException( false ), m_usedStream( false ) {} ResultBuilder::~ResultBuilder() { #if defined(CATCH_CONFIG_FAST_COMPILE) if ( m_guardException ) { stream().oss << "Exception translation was disabled by CATCH_CONFIG_FAST_COMPILE"; captureResult( ResultWas::ThrewException ); getCurrentContext().getResultCapture()->exceptionEarlyReported(); } #endif } ResultBuilder& ResultBuilder::setResultType( ResultWas::OfType result ) { m_data.resultType = result; return *this; } ResultBuilder& ResultBuilder::setResultType( bool result ) { m_data.resultType = result ? ResultWas::Ok : ResultWas::ExpressionFailed; return *this; } void ResultBuilder::endExpression( DecomposedExpression const& expr ) { // Flip bool results if FalseTest flag is set if( isFalseTest( m_assertionInfo.resultDisposition ) ) { m_data.negate( expr.isBinaryExpression() ); } getResultCapture().assertionRun(); if(getCurrentContext().getConfig()->includeSuccessfulResults() || m_data.resultType != ResultWas::Ok) { AssertionResult result = build( expr ); handleResult( result ); } else getResultCapture().assertionPassed(); } void ResultBuilder::useActiveException( ResultDisposition::Flags resultDisposition ) { m_assertionInfo.resultDisposition = resultDisposition; stream().oss << Catch::translateActiveException(); captureResult( ResultWas::ThrewException ); } void ResultBuilder::captureResult( ResultWas::OfType resultType ) { setResultType( resultType ); captureExpression(); } void ResultBuilder::captureExpectedException( std::string const& expectedMessage ) { if( expectedMessage.empty() ) captureExpectedException( Matchers::Impl::MatchAllOf() ); else captureExpectedException( Matchers::Equals( expectedMessage ) ); } void ResultBuilder::captureExpectedException( Matchers::Impl::MatcherBase const& matcher ) { assert( !isFalseTest( m_assertionInfo.resultDisposition ) ); AssertionResultData data = m_data; data.resultType = ResultWas::Ok; data.reconstructedExpression = capturedExpressionWithSecondArgument(m_assertionInfo.capturedExpression, m_assertionInfo.secondArg); std::string actualMessage = Catch::translateActiveException(); if( !matcher.match( actualMessage ) ) { data.resultType = ResultWas::ExpressionFailed; data.reconstructedExpression = actualMessage; } AssertionResult result( m_assertionInfo, data ); handleResult( result ); } void ResultBuilder::captureExpression() { AssertionResult result = build(); handleResult( result ); } void ResultBuilder::handleResult( AssertionResult const& result ) { getResultCapture().assertionEnded( result ); if( !result.isOk() ) { if( getCurrentContext().getConfig()->shouldDebugBreak() ) m_shouldDebugBreak = true; if( getCurrentContext().getRunner()->aborting() || (m_assertionInfo.resultDisposition & ResultDisposition::Normal) ) m_shouldThrow = true; } } void ResultBuilder::react() { #if defined(CATCH_CONFIG_FAST_COMPILE) if (m_shouldDebugBreak) { /////////////////////////////////////////////////////////////////// // To inspect the state during test, you need to go one level up the callstack // To go back to the test and change execution, jump over the throw statement /////////////////////////////////////////////////////////////////// CATCH_BREAK_INTO_DEBUGGER(); } #endif if( m_shouldThrow ) throw Catch::TestFailureException(); } bool ResultBuilder::shouldDebugBreak() const { return m_shouldDebugBreak; } bool ResultBuilder::allowThrows() const { return getCurrentContext().getConfig()->allowThrows(); } AssertionResult ResultBuilder::build() const { return build( *this ); } // CAVEAT: The returned AssertionResult stores a pointer to the argument expr, // a temporary DecomposedExpression, which in turn holds references to // operands, possibly temporary as well. // It should immediately be passed to handleResult; if the expression // needs to be reported, its string expansion must be composed before // the temporaries are destroyed. AssertionResult ResultBuilder::build( DecomposedExpression const& expr ) const { assert( m_data.resultType != ResultWas::Unknown ); AssertionResultData data = m_data; if(m_usedStream) data.message = m_stream().oss.str(); data.decomposedExpression = &expr; // for lazy reconstruction return AssertionResult( m_assertionInfo, data ); } void ResultBuilder::reconstructExpression( std::string& dest ) const { dest = capturedExpressionWithSecondArgument(m_assertionInfo.capturedExpression, m_assertionInfo.secondArg); } void ResultBuilder::setExceptionGuard() { m_guardException = true; } void ResultBuilder::unsetExceptionGuard() { m_guardException = false; } } // end namespace Catch // #included from: catch_tag_alias_registry.hpp #define TWOBLUECUBES_CATCH_TAG_ALIAS_REGISTRY_HPP_INCLUDED namespace Catch { TagAliasRegistry::~TagAliasRegistry() {} Option TagAliasRegistry::find( std::string const& alias ) const { std::map::const_iterator it = m_registry.find( alias ); if( it != m_registry.end() ) return it->second; else return Option(); } std::string TagAliasRegistry::expandAliases( std::string const& unexpandedTestSpec ) const { std::string expandedTestSpec = unexpandedTestSpec; for( std::map::const_iterator it = m_registry.begin(), itEnd = m_registry.end(); it != itEnd; ++it ) { std::size_t pos = expandedTestSpec.find( it->first ); if( pos != std::string::npos ) { expandedTestSpec = expandedTestSpec.substr( 0, pos ) + it->second.tag + expandedTestSpec.substr( pos + it->first.size() ); } } return expandedTestSpec; } void TagAliasRegistry::add( std::string const& alias, std::string const& tag, SourceLineInfo const& lineInfo ) { if( !startsWith( alias, "[@" ) || !endsWith( alias, ']' ) ) { std::ostringstream oss; oss << Colour( Colour::Red ) << "error: tag alias, \"" << alias << "\" is not of the form [@alias name].\n" << Colour( Colour::FileName ) << lineInfo << '\n'; throw std::domain_error( oss.str().c_str() ); } if( !m_registry.insert( std::make_pair( alias, TagAlias( tag, lineInfo ) ) ).second ) { std::ostringstream oss; oss << Colour( Colour::Red ) << "error: tag alias, \"" << alias << "\" already registered.\n" << "\tFirst seen at " << Colour( Colour::Red ) << find(alias)->lineInfo << '\n' << Colour( Colour::Red ) << "\tRedefined at " << Colour( Colour::FileName) << lineInfo << '\n'; throw std::domain_error( oss.str().c_str() ); } } ITagAliasRegistry::~ITagAliasRegistry() {} ITagAliasRegistry const& ITagAliasRegistry::get() { return getRegistryHub().getTagAliasRegistry(); } RegistrarForTagAliases::RegistrarForTagAliases( char const* alias, char const* tag, SourceLineInfo const& lineInfo ) { getMutableRegistryHub().registerTagAlias( alias, tag, lineInfo ); } } // end namespace Catch // #included from: catch_matchers_string.hpp namespace Catch { namespace Matchers { namespace StdString { CasedString::CasedString( std::string const& str, CaseSensitive::Choice caseSensitivity ) : m_caseSensitivity( caseSensitivity ), m_str( adjustString( str ) ) {} std::string CasedString::adjustString( std::string const& str ) const { return m_caseSensitivity == CaseSensitive::No ? toLower( str ) : str; } std::string CasedString::caseSensitivitySuffix() const { return m_caseSensitivity == CaseSensitive::No ? " (case insensitive)" : std::string(); } StringMatcherBase::StringMatcherBase( std::string const& operation, CasedString const& comparator ) : m_comparator( comparator ), m_operation( operation ) { } std::string StringMatcherBase::describe() const { std::string description; description.reserve(5 + m_operation.size() + m_comparator.m_str.size() + m_comparator.caseSensitivitySuffix().size()); description += m_operation; description += ": \""; description += m_comparator.m_str; description += "\""; description += m_comparator.caseSensitivitySuffix(); return description; } EqualsMatcher::EqualsMatcher( CasedString const& comparator ) : StringMatcherBase( "equals", comparator ) {} bool EqualsMatcher::match( std::string const& source ) const { return m_comparator.adjustString( source ) == m_comparator.m_str; } ContainsMatcher::ContainsMatcher( CasedString const& comparator ) : StringMatcherBase( "contains", comparator ) {} bool ContainsMatcher::match( std::string const& source ) const { return contains( m_comparator.adjustString( source ), m_comparator.m_str ); } StartsWithMatcher::StartsWithMatcher( CasedString const& comparator ) : StringMatcherBase( "starts with", comparator ) {} bool StartsWithMatcher::match( std::string const& source ) const { return startsWith( m_comparator.adjustString( source ), m_comparator.m_str ); } EndsWithMatcher::EndsWithMatcher( CasedString const& comparator ) : StringMatcherBase( "ends with", comparator ) {} bool EndsWithMatcher::match( std::string const& source ) const { return endsWith( m_comparator.adjustString( source ), m_comparator.m_str ); } } // namespace StdString StdString::EqualsMatcher Equals( std::string const& str, CaseSensitive::Choice caseSensitivity ) { return StdString::EqualsMatcher( StdString::CasedString( str, caseSensitivity) ); } StdString::ContainsMatcher Contains( std::string const& str, CaseSensitive::Choice caseSensitivity ) { return StdString::ContainsMatcher( StdString::CasedString( str, caseSensitivity) ); } StdString::EndsWithMatcher EndsWith( std::string const& str, CaseSensitive::Choice caseSensitivity ) { return StdString::EndsWithMatcher( StdString::CasedString( str, caseSensitivity) ); } StdString::StartsWithMatcher StartsWith( std::string const& str, CaseSensitive::Choice caseSensitivity ) { return StdString::StartsWithMatcher( StdString::CasedString( str, caseSensitivity) ); } } // namespace Matchers } // namespace Catch // #included from: ../reporters/catch_reporter_multi.hpp #define TWOBLUECUBES_CATCH_REPORTER_MULTI_HPP_INCLUDED namespace Catch { class MultipleReporters : public SharedImpl { typedef std::vector > Reporters; Reporters m_reporters; public: void add( Ptr const& reporter ) { m_reporters.push_back( reporter ); } public: // IStreamingReporter virtual ReporterPreferences getPreferences() const CATCH_OVERRIDE { return m_reporters[0]->getPreferences(); } virtual void noMatchingTestCases( std::string const& spec ) CATCH_OVERRIDE { for( Reporters::const_iterator it = m_reporters.begin(), itEnd = m_reporters.end(); it != itEnd; ++it ) (*it)->noMatchingTestCases( spec ); } virtual void testRunStarting( TestRunInfo const& testRunInfo ) CATCH_OVERRIDE { for( Reporters::const_iterator it = m_reporters.begin(), itEnd = m_reporters.end(); it != itEnd; ++it ) (*it)->testRunStarting( testRunInfo ); } virtual void testGroupStarting( GroupInfo const& groupInfo ) CATCH_OVERRIDE { for( Reporters::const_iterator it = m_reporters.begin(), itEnd = m_reporters.end(); it != itEnd; ++it ) (*it)->testGroupStarting( groupInfo ); } virtual void testCaseStarting( TestCaseInfo const& testInfo ) CATCH_OVERRIDE { for( Reporters::const_iterator it = m_reporters.begin(), itEnd = m_reporters.end(); it != itEnd; ++it ) (*it)->testCaseStarting( testInfo ); } virtual void sectionStarting( SectionInfo const& sectionInfo ) CATCH_OVERRIDE { for( Reporters::const_iterator it = m_reporters.begin(), itEnd = m_reporters.end(); it != itEnd; ++it ) (*it)->sectionStarting( sectionInfo ); } virtual void assertionStarting( AssertionInfo const& assertionInfo ) CATCH_OVERRIDE { for( Reporters::const_iterator it = m_reporters.begin(), itEnd = m_reporters.end(); it != itEnd; ++it ) (*it)->assertionStarting( assertionInfo ); } // The return value indicates if the messages buffer should be cleared: virtual bool assertionEnded( AssertionStats const& assertionStats ) CATCH_OVERRIDE { bool clearBuffer = false; for( Reporters::const_iterator it = m_reporters.begin(), itEnd = m_reporters.end(); it != itEnd; ++it ) clearBuffer |= (*it)->assertionEnded( assertionStats ); return clearBuffer; } virtual void sectionEnded( SectionStats const& sectionStats ) CATCH_OVERRIDE { for( Reporters::const_iterator it = m_reporters.begin(), itEnd = m_reporters.end(); it != itEnd; ++it ) (*it)->sectionEnded( sectionStats ); } virtual void testCaseEnded( TestCaseStats const& testCaseStats ) CATCH_OVERRIDE { for( Reporters::const_iterator it = m_reporters.begin(), itEnd = m_reporters.end(); it != itEnd; ++it ) (*it)->testCaseEnded( testCaseStats ); } virtual void testGroupEnded( TestGroupStats const& testGroupStats ) CATCH_OVERRIDE { for( Reporters::const_iterator it = m_reporters.begin(), itEnd = m_reporters.end(); it != itEnd; ++it ) (*it)->testGroupEnded( testGroupStats ); } virtual void testRunEnded( TestRunStats const& testRunStats ) CATCH_OVERRIDE { for( Reporters::const_iterator it = m_reporters.begin(), itEnd = m_reporters.end(); it != itEnd; ++it ) (*it)->testRunEnded( testRunStats ); } virtual void skipTest( TestCaseInfo const& testInfo ) CATCH_OVERRIDE { for( Reporters::const_iterator it = m_reporters.begin(), itEnd = m_reporters.end(); it != itEnd; ++it ) (*it)->skipTest( testInfo ); } virtual MultipleReporters* tryAsMulti() CATCH_OVERRIDE { return this; } }; Ptr addReporter( Ptr const& existingReporter, Ptr const& additionalReporter ) { Ptr resultingReporter; if( existingReporter ) { MultipleReporters* multi = existingReporter->tryAsMulti(); if( !multi ) { multi = new MultipleReporters; resultingReporter = Ptr( multi ); if( existingReporter ) multi->add( existingReporter ); } else resultingReporter = existingReporter; multi->add( additionalReporter ); } else resultingReporter = additionalReporter; return resultingReporter; } } // end namespace Catch // #included from: ../reporters/catch_reporter_xml.hpp #define TWOBLUECUBES_CATCH_REPORTER_XML_HPP_INCLUDED // #included from: catch_reporter_bases.hpp #define TWOBLUECUBES_CATCH_REPORTER_BASES_HPP_INCLUDED #include #include #include #include namespace Catch { namespace { // Because formatting using c++ streams is stateful, drop down to C is required // Alternatively we could use stringstream, but its performance is... not good. std::string getFormattedDuration( double duration ) { // Max exponent + 1 is required to represent the whole part // + 1 for decimal point // + 3 for the 3 decimal places // + 1 for null terminator const size_t maxDoubleSize = DBL_MAX_10_EXP + 1 + 1 + 3 + 1; char buffer[maxDoubleSize]; // Save previous errno, to prevent sprintf from overwriting it ErrnoGuard guard; #ifdef _MSC_VER sprintf_s(buffer, "%.3f", duration); #else sprintf(buffer, "%.3f", duration); #endif return std::string(buffer); } } struct StreamingReporterBase : SharedImpl { StreamingReporterBase( ReporterConfig const& _config ) : m_config( _config.fullConfig() ), stream( _config.stream() ) { m_reporterPrefs.shouldRedirectStdOut = false; } virtual ReporterPreferences getPreferences() const CATCH_OVERRIDE { return m_reporterPrefs; } virtual ~StreamingReporterBase() CATCH_OVERRIDE; virtual void noMatchingTestCases( std::string const& ) CATCH_OVERRIDE {} virtual void testRunStarting( TestRunInfo const& _testRunInfo ) CATCH_OVERRIDE { currentTestRunInfo = _testRunInfo; } virtual void testGroupStarting( GroupInfo const& _groupInfo ) CATCH_OVERRIDE { currentGroupInfo = _groupInfo; } virtual void testCaseStarting( TestCaseInfo const& _testInfo ) CATCH_OVERRIDE { currentTestCaseInfo = _testInfo; } virtual void sectionStarting( SectionInfo const& _sectionInfo ) CATCH_OVERRIDE { m_sectionStack.push_back( _sectionInfo ); } virtual void sectionEnded( SectionStats const& /* _sectionStats */ ) CATCH_OVERRIDE { m_sectionStack.pop_back(); } virtual void testCaseEnded( TestCaseStats const& /* _testCaseStats */ ) CATCH_OVERRIDE { currentTestCaseInfo.reset(); } virtual void testGroupEnded( TestGroupStats const& /* _testGroupStats */ ) CATCH_OVERRIDE { currentGroupInfo.reset(); } virtual void testRunEnded( TestRunStats const& /* _testRunStats */ ) CATCH_OVERRIDE { currentTestCaseInfo.reset(); currentGroupInfo.reset(); currentTestRunInfo.reset(); } virtual void skipTest( TestCaseInfo const& ) CATCH_OVERRIDE { // Don't do anything with this by default. // It can optionally be overridden in the derived class. } Ptr m_config; std::ostream& stream; LazyStat currentTestRunInfo; LazyStat currentGroupInfo; LazyStat currentTestCaseInfo; std::vector m_sectionStack; ReporterPreferences m_reporterPrefs; }; struct CumulativeReporterBase : SharedImpl { template struct Node : SharedImpl<> { explicit Node( T const& _value ) : value( _value ) {} virtual ~Node() {} typedef std::vector > ChildNodes; T value; ChildNodes children; }; struct SectionNode : SharedImpl<> { explicit SectionNode( SectionStats const& _stats ) : stats( _stats ) {} virtual ~SectionNode(); bool operator == ( SectionNode const& other ) const { return stats.sectionInfo.lineInfo == other.stats.sectionInfo.lineInfo; } bool operator == ( Ptr const& other ) const { return operator==( *other ); } SectionStats stats; typedef std::vector > ChildSections; typedef std::vector Assertions; ChildSections childSections; Assertions assertions; std::string stdOut; std::string stdErr; }; struct BySectionInfo { BySectionInfo( SectionInfo const& other ) : m_other( other ) {} BySectionInfo( BySectionInfo const& other ) : m_other( other.m_other ) {} bool operator() ( Ptr const& node ) const { return ((node->stats.sectionInfo.name == m_other.name) && (node->stats.sectionInfo.lineInfo == m_other.lineInfo)); } private: void operator=( BySectionInfo const& ); SectionInfo const& m_other; }; typedef Node TestCaseNode; typedef Node TestGroupNode; typedef Node TestRunNode; CumulativeReporterBase( ReporterConfig const& _config ) : m_config( _config.fullConfig() ), stream( _config.stream() ) { m_reporterPrefs.shouldRedirectStdOut = false; } ~CumulativeReporterBase(); virtual ReporterPreferences getPreferences() const CATCH_OVERRIDE { return m_reporterPrefs; } virtual void testRunStarting( TestRunInfo const& ) CATCH_OVERRIDE {} virtual void testGroupStarting( GroupInfo const& ) CATCH_OVERRIDE {} virtual void testCaseStarting( TestCaseInfo const& ) CATCH_OVERRIDE {} virtual void sectionStarting( SectionInfo const& sectionInfo ) CATCH_OVERRIDE { SectionStats incompleteStats( sectionInfo, Counts(), 0, false ); Ptr node; if( m_sectionStack.empty() ) { if( !m_rootSection ) m_rootSection = new SectionNode( incompleteStats ); node = m_rootSection; } else { SectionNode& parentNode = *m_sectionStack.back(); SectionNode::ChildSections::const_iterator it = std::find_if( parentNode.childSections.begin(), parentNode.childSections.end(), BySectionInfo( sectionInfo ) ); if( it == parentNode.childSections.end() ) { node = new SectionNode( incompleteStats ); parentNode.childSections.push_back( node ); } else node = *it; } m_sectionStack.push_back( node ); m_deepestSection = node; } virtual void assertionStarting( AssertionInfo const& ) CATCH_OVERRIDE {} virtual bool assertionEnded( AssertionStats const& assertionStats ) CATCH_OVERRIDE { assert( !m_sectionStack.empty() ); SectionNode& sectionNode = *m_sectionStack.back(); sectionNode.assertions.push_back( assertionStats ); // AssertionResult holds a pointer to a temporary DecomposedExpression, // which getExpandedExpression() calls to build the expression string. // Our section stack copy of the assertionResult will likely outlive the // temporary, so it must be expanded or discarded now to avoid calling // a destroyed object later. prepareExpandedExpression( sectionNode.assertions.back().assertionResult ); return true; } virtual void sectionEnded( SectionStats const& sectionStats ) CATCH_OVERRIDE { assert( !m_sectionStack.empty() ); SectionNode& node = *m_sectionStack.back(); node.stats = sectionStats; m_sectionStack.pop_back(); } virtual void testCaseEnded( TestCaseStats const& testCaseStats ) CATCH_OVERRIDE { Ptr node = new TestCaseNode( testCaseStats ); assert( m_sectionStack.size() == 0 ); node->children.push_back( m_rootSection ); m_testCases.push_back( node ); m_rootSection.reset(); assert( m_deepestSection ); m_deepestSection->stdOut = testCaseStats.stdOut; m_deepestSection->stdErr = testCaseStats.stdErr; } virtual void testGroupEnded( TestGroupStats const& testGroupStats ) CATCH_OVERRIDE { Ptr node = new TestGroupNode( testGroupStats ); node->children.swap( m_testCases ); m_testGroups.push_back( node ); } virtual void testRunEnded( TestRunStats const& testRunStats ) CATCH_OVERRIDE { Ptr node = new TestRunNode( testRunStats ); node->children.swap( m_testGroups ); m_testRuns.push_back( node ); testRunEndedCumulative(); } virtual void testRunEndedCumulative() = 0; virtual void skipTest( TestCaseInfo const& ) CATCH_OVERRIDE {} virtual void prepareExpandedExpression( AssertionResult& result ) const { if( result.isOk() ) result.discardDecomposedExpression(); else result.expandDecomposedExpression(); } Ptr m_config; std::ostream& stream; std::vector m_assertions; std::vector > > m_sections; std::vector > m_testCases; std::vector > m_testGroups; std::vector > m_testRuns; Ptr m_rootSection; Ptr m_deepestSection; std::vector > m_sectionStack; ReporterPreferences m_reporterPrefs; }; template char const* getLineOfChars() { static char line[CATCH_CONFIG_CONSOLE_WIDTH] = {0}; if( !*line ) { std::memset( line, C, CATCH_CONFIG_CONSOLE_WIDTH-1 ); line[CATCH_CONFIG_CONSOLE_WIDTH-1] = 0; } return line; } struct TestEventListenerBase : StreamingReporterBase { TestEventListenerBase( ReporterConfig const& _config ) : StreamingReporterBase( _config ) {} virtual void assertionStarting( AssertionInfo const& ) CATCH_OVERRIDE {} virtual bool assertionEnded( AssertionStats const& ) CATCH_OVERRIDE { return false; } }; } // end namespace Catch // #included from: ../internal/catch_reporter_registrars.hpp #define TWOBLUECUBES_CATCH_REPORTER_REGISTRARS_HPP_INCLUDED namespace Catch { template class LegacyReporterRegistrar { class ReporterFactory : public IReporterFactory { virtual IStreamingReporter* create( ReporterConfig const& config ) const { return new LegacyReporterAdapter( new T( config ) ); } virtual std::string getDescription() const { return T::getDescription(); } }; public: LegacyReporterRegistrar( std::string const& name ) { getMutableRegistryHub().registerReporter( name, new ReporterFactory() ); } }; template class ReporterRegistrar { class ReporterFactory : public SharedImpl { // *** Please Note ***: // - If you end up here looking at a compiler error because it's trying to register // your custom reporter class be aware that the native reporter interface has changed // to IStreamingReporter. The "legacy" interface, IReporter, is still supported via // an adapter. Just use REGISTER_LEGACY_REPORTER to take advantage of the adapter. // However please consider updating to the new interface as the old one is now // deprecated and will probably be removed quite soon! // Please contact me via github if you have any questions at all about this. // In fact, ideally, please contact me anyway to let me know you've hit this - as I have // no idea who is actually using custom reporters at all (possibly no-one!). // The new interface is designed to minimise exposure to interface changes in the future. virtual IStreamingReporter* create( ReporterConfig const& config ) const { return new T( config ); } virtual std::string getDescription() const { return T::getDescription(); } }; public: ReporterRegistrar( std::string const& name ) { getMutableRegistryHub().registerReporter( name, new ReporterFactory() ); } }; template class ListenerRegistrar { class ListenerFactory : public SharedImpl { virtual IStreamingReporter* create( ReporterConfig const& config ) const { return new T( config ); } virtual std::string getDescription() const { return std::string(); } }; public: ListenerRegistrar() { getMutableRegistryHub().registerListener( new ListenerFactory() ); } }; } #define INTERNAL_CATCH_REGISTER_LEGACY_REPORTER( name, reporterType ) \ namespace{ Catch::LegacyReporterRegistrar catch_internal_RegistrarFor##reporterType( name ); } #define INTERNAL_CATCH_REGISTER_REPORTER( name, reporterType ) \ namespace{ Catch::ReporterRegistrar catch_internal_RegistrarFor##reporterType( name ); } // Deprecated - use the form without INTERNAL_ #define INTERNAL_CATCH_REGISTER_LISTENER( listenerType ) \ namespace{ Catch::ListenerRegistrar catch_internal_RegistrarFor##listenerType; } #define CATCH_REGISTER_LISTENER( listenerType ) \ namespace{ Catch::ListenerRegistrar catch_internal_RegistrarFor##listenerType; } // #included from: ../internal/catch_xmlwriter.hpp #define TWOBLUECUBES_CATCH_XMLWRITER_HPP_INCLUDED #include #include #include #include namespace Catch { class XmlEncode { public: enum ForWhat { ForTextNodes, ForAttributes }; XmlEncode( std::string const& str, ForWhat forWhat = ForTextNodes ) : m_str( str ), m_forWhat( forWhat ) {} void encodeTo( std::ostream& os ) const { // Apostrophe escaping not necessary if we always use " to write attributes // (see: http://www.w3.org/TR/xml/#syntax) for( std::size_t i = 0; i < m_str.size(); ++ i ) { char c = m_str[i]; switch( c ) { case '<': os << "<"; break; case '&': os << "&"; break; case '>': // See: http://www.w3.org/TR/xml/#syntax if( i > 2 && m_str[i-1] == ']' && m_str[i-2] == ']' ) os << ">"; else os << c; break; case '\"': if( m_forWhat == ForAttributes ) os << """; else os << c; break; default: // Escape control chars - based on contribution by @espenalb in PR #465 and // by @mrpi PR #588 if ( ( c >= 0 && c < '\x09' ) || ( c > '\x0D' && c < '\x20') || c=='\x7F' ) { // see http://stackoverflow.com/questions/404107/why-are-control-characters-illegal-in-xml-1-0 os << "\\x" << std::uppercase << std::hex << std::setfill('0') << std::setw(2) << static_cast( c ); } else os << c; } } } friend std::ostream& operator << ( std::ostream& os, XmlEncode const& xmlEncode ) { xmlEncode.encodeTo( os ); return os; } private: std::string m_str; ForWhat m_forWhat; }; class XmlWriter { public: class ScopedElement { public: ScopedElement( XmlWriter* writer ) : m_writer( writer ) {} ScopedElement( ScopedElement const& other ) : m_writer( other.m_writer ){ other.m_writer = CATCH_NULL; } ~ScopedElement() { if( m_writer ) m_writer->endElement(); } ScopedElement& writeText( std::string const& text, bool indent = true ) { m_writer->writeText( text, indent ); return *this; } template ScopedElement& writeAttribute( std::string const& name, T const& attribute ) { m_writer->writeAttribute( name, attribute ); return *this; } private: mutable XmlWriter* m_writer; }; XmlWriter() : m_tagIsOpen( false ), m_needsNewline( false ), m_os( Catch::cout() ) { writeDeclaration(); } XmlWriter( std::ostream& os ) : m_tagIsOpen( false ), m_needsNewline( false ), m_os( os ) { writeDeclaration(); } ~XmlWriter() { while( !m_tags.empty() ) endElement(); } XmlWriter& startElement( std::string const& name ) { ensureTagClosed(); newlineIfNecessary(); m_os << m_indent << '<' << name; m_tags.push_back( name ); m_indent += " "; m_tagIsOpen = true; return *this; } ScopedElement scopedElement( std::string const& name ) { ScopedElement scoped( this ); startElement( name ); return scoped; } XmlWriter& endElement() { newlineIfNecessary(); m_indent = m_indent.substr( 0, m_indent.size()-2 ); if( m_tagIsOpen ) { m_os << "/>"; m_tagIsOpen = false; } else { m_os << m_indent << ""; } m_os << std::endl; m_tags.pop_back(); return *this; } XmlWriter& writeAttribute( std::string const& name, std::string const& attribute ) { if( !name.empty() && !attribute.empty() ) m_os << ' ' << name << "=\"" << XmlEncode( attribute, XmlEncode::ForAttributes ) << '"'; return *this; } XmlWriter& writeAttribute( std::string const& name, bool attribute ) { m_os << ' ' << name << "=\"" << ( attribute ? "true" : "false" ) << '"'; return *this; } template XmlWriter& writeAttribute( std::string const& name, T const& attribute ) { std::ostringstream oss; oss << attribute; return writeAttribute( name, oss.str() ); } XmlWriter& writeText( std::string const& text, bool indent = true ) { if( !text.empty() ){ bool tagWasOpen = m_tagIsOpen; ensureTagClosed(); if( tagWasOpen && indent ) m_os << m_indent; m_os << XmlEncode( text ); m_needsNewline = true; } return *this; } XmlWriter& writeComment( std::string const& text ) { ensureTagClosed(); m_os << m_indent << ""; m_needsNewline = true; return *this; } void writeStylesheetRef( std::string const& url ) { m_os << "\n"; } XmlWriter& writeBlankLine() { ensureTagClosed(); m_os << '\n'; return *this; } void ensureTagClosed() { if( m_tagIsOpen ) { m_os << ">" << std::endl; m_tagIsOpen = false; } } private: XmlWriter( XmlWriter const& ); void operator=( XmlWriter const& ); void writeDeclaration() { m_os << "\n"; } void newlineIfNecessary() { if( m_needsNewline ) { m_os << std::endl; m_needsNewline = false; } } bool m_tagIsOpen; bool m_needsNewline; std::vector m_tags; std::string m_indent; std::ostream& m_os; }; } namespace Catch { class XmlReporter : public StreamingReporterBase { public: XmlReporter( ReporterConfig const& _config ) : StreamingReporterBase( _config ), m_xml(_config.stream()), m_sectionDepth( 0 ) { m_reporterPrefs.shouldRedirectStdOut = true; } virtual ~XmlReporter() CATCH_OVERRIDE; static std::string getDescription() { return "Reports test results as an XML document"; } virtual std::string getStylesheetRef() const { return std::string(); } void writeSourceInfo( SourceLineInfo const& sourceInfo ) { m_xml .writeAttribute( "filename", sourceInfo.file ) .writeAttribute( "line", sourceInfo.line ); } public: // StreamingReporterBase virtual void noMatchingTestCases( std::string const& s ) CATCH_OVERRIDE { StreamingReporterBase::noMatchingTestCases( s ); } virtual void testRunStarting( TestRunInfo const& testInfo ) CATCH_OVERRIDE { StreamingReporterBase::testRunStarting( testInfo ); std::string stylesheetRef = getStylesheetRef(); if( !stylesheetRef.empty() ) m_xml.writeStylesheetRef( stylesheetRef ); m_xml.startElement( "Catch" ); if( !m_config->name().empty() ) m_xml.writeAttribute( "name", m_config->name() ); } virtual void testGroupStarting( GroupInfo const& groupInfo ) CATCH_OVERRIDE { StreamingReporterBase::testGroupStarting( groupInfo ); m_xml.startElement( "Group" ) .writeAttribute( "name", groupInfo.name ); } virtual void testCaseStarting( TestCaseInfo const& testInfo ) CATCH_OVERRIDE { StreamingReporterBase::testCaseStarting(testInfo); m_xml.startElement( "TestCase" ) .writeAttribute( "name", trim( testInfo.name ) ) .writeAttribute( "description", testInfo.description ) .writeAttribute( "tags", testInfo.tagsAsString ); writeSourceInfo( testInfo.lineInfo ); if ( m_config->showDurations() == ShowDurations::Always ) m_testCaseTimer.start(); m_xml.ensureTagClosed(); } virtual void sectionStarting( SectionInfo const& sectionInfo ) CATCH_OVERRIDE { StreamingReporterBase::sectionStarting( sectionInfo ); if( m_sectionDepth++ > 0 ) { m_xml.startElement( "Section" ) .writeAttribute( "name", trim( sectionInfo.name ) ) .writeAttribute( "description", sectionInfo.description ); writeSourceInfo( sectionInfo.lineInfo ); m_xml.ensureTagClosed(); } } virtual void assertionStarting( AssertionInfo const& ) CATCH_OVERRIDE { } virtual bool assertionEnded( AssertionStats const& assertionStats ) CATCH_OVERRIDE { AssertionResult const& result = assertionStats.assertionResult; bool includeResults = m_config->includeSuccessfulResults() || !result.isOk(); if( includeResults || result.getResultType() == ResultWas::Warning ) { // Print any info messages in tags. for( std::vector::const_iterator it = assertionStats.infoMessages.begin(), itEnd = assertionStats.infoMessages.end(); it != itEnd; ++it ) { if( it->type == ResultWas::Info && includeResults ) { m_xml.scopedElement( "Info" ) .writeText( it->message ); } else if ( it->type == ResultWas::Warning ) { m_xml.scopedElement( "Warning" ) .writeText( it->message ); } } } // Drop out if result was successful but we're not printing them. if( !includeResults && result.getResultType() != ResultWas::Warning ) return true; // Print the expression if there is one. if( result.hasExpression() ) { m_xml.startElement( "Expression" ) .writeAttribute( "success", result.succeeded() ) .writeAttribute( "type", result.getTestMacroName() ); writeSourceInfo( result.getSourceInfo() ); m_xml.scopedElement( "Original" ) .writeText( result.getExpression() ); m_xml.scopedElement( "Expanded" ) .writeText( result.getExpandedExpression() ); } // And... Print a result applicable to each result type. switch( result.getResultType() ) { case ResultWas::ThrewException: m_xml.startElement( "Exception" ); writeSourceInfo( result.getSourceInfo() ); m_xml.writeText( result.getMessage() ); m_xml.endElement(); break; case ResultWas::FatalErrorCondition: m_xml.startElement( "FatalErrorCondition" ); writeSourceInfo( result.getSourceInfo() ); m_xml.writeText( result.getMessage() ); m_xml.endElement(); break; case ResultWas::Info: m_xml.scopedElement( "Info" ) .writeText( result.getMessage() ); break; case ResultWas::Warning: // Warning will already have been written break; case ResultWas::ExplicitFailure: m_xml.startElement( "Failure" ); writeSourceInfo( result.getSourceInfo() ); m_xml.writeText( result.getMessage() ); m_xml.endElement(); break; default: break; } if( result.hasExpression() ) m_xml.endElement(); return true; } virtual void sectionEnded( SectionStats const& sectionStats ) CATCH_OVERRIDE { StreamingReporterBase::sectionEnded( sectionStats ); if( --m_sectionDepth > 0 ) { XmlWriter::ScopedElement e = m_xml.scopedElement( "OverallResults" ); e.writeAttribute( "successes", sectionStats.assertions.passed ); e.writeAttribute( "failures", sectionStats.assertions.failed ); e.writeAttribute( "expectedFailures", sectionStats.assertions.failedButOk ); if ( m_config->showDurations() == ShowDurations::Always ) e.writeAttribute( "durationInSeconds", sectionStats.durationInSeconds ); m_xml.endElement(); } } virtual void testCaseEnded( TestCaseStats const& testCaseStats ) CATCH_OVERRIDE { StreamingReporterBase::testCaseEnded( testCaseStats ); XmlWriter::ScopedElement e = m_xml.scopedElement( "OverallResult" ); e.writeAttribute( "success", testCaseStats.totals.assertions.allOk() ); if ( m_config->showDurations() == ShowDurations::Always ) e.writeAttribute( "durationInSeconds", m_testCaseTimer.getElapsedSeconds() ); if( !testCaseStats.stdOut.empty() ) m_xml.scopedElement( "StdOut" ).writeText( trim( testCaseStats.stdOut ), false ); if( !testCaseStats.stdErr.empty() ) m_xml.scopedElement( "StdErr" ).writeText( trim( testCaseStats.stdErr ), false ); m_xml.endElement(); } virtual void testGroupEnded( TestGroupStats const& testGroupStats ) CATCH_OVERRIDE { StreamingReporterBase::testGroupEnded( testGroupStats ); // TODO: Check testGroupStats.aborting and act accordingly. m_xml.scopedElement( "OverallResults" ) .writeAttribute( "successes", testGroupStats.totals.assertions.passed ) .writeAttribute( "failures", testGroupStats.totals.assertions.failed ) .writeAttribute( "expectedFailures", testGroupStats.totals.assertions.failedButOk ); m_xml.endElement(); } virtual void testRunEnded( TestRunStats const& testRunStats ) CATCH_OVERRIDE { StreamingReporterBase::testRunEnded( testRunStats ); m_xml.scopedElement( "OverallResults" ) .writeAttribute( "successes", testRunStats.totals.assertions.passed ) .writeAttribute( "failures", testRunStats.totals.assertions.failed ) .writeAttribute( "expectedFailures", testRunStats.totals.assertions.failedButOk ); m_xml.endElement(); } private: Timer m_testCaseTimer; XmlWriter m_xml; int m_sectionDepth; }; INTERNAL_CATCH_REGISTER_REPORTER( "xml", XmlReporter ) } // end namespace Catch // #included from: ../reporters/catch_reporter_junit.hpp #define TWOBLUECUBES_CATCH_REPORTER_JUNIT_HPP_INCLUDED #include namespace Catch { namespace { std::string getCurrentTimestamp() { // Beware, this is not reentrant because of backward compatibility issues // Also, UTC only, again because of backward compatibility (%z is C++11) time_t rawtime; std::time(&rawtime); const size_t timeStampSize = sizeof("2017-01-16T17:06:45Z"); #ifdef _MSC_VER std::tm timeInfo = {}; gmtime_s(&timeInfo, &rawtime); #else std::tm* timeInfo; timeInfo = std::gmtime(&rawtime); #endif char timeStamp[timeStampSize]; const char * const fmt = "%Y-%m-%dT%H:%M:%SZ"; #ifdef _MSC_VER std::strftime(timeStamp, timeStampSize, fmt, &timeInfo); #else std::strftime(timeStamp, timeStampSize, fmt, timeInfo); #endif return std::string(timeStamp); } } class JunitReporter : public CumulativeReporterBase { public: JunitReporter( ReporterConfig const& _config ) : CumulativeReporterBase( _config ), xml( _config.stream() ), unexpectedExceptions( 0 ), m_okToFail( false ) { m_reporterPrefs.shouldRedirectStdOut = true; } virtual ~JunitReporter() CATCH_OVERRIDE; static std::string getDescription() { return "Reports test results in an XML format that looks like Ant's junitreport target"; } virtual void noMatchingTestCases( std::string const& /*spec*/ ) CATCH_OVERRIDE {} virtual void testRunStarting( TestRunInfo const& runInfo ) CATCH_OVERRIDE { CumulativeReporterBase::testRunStarting( runInfo ); xml.startElement( "testsuites" ); } virtual void testGroupStarting( GroupInfo const& groupInfo ) CATCH_OVERRIDE { suiteTimer.start(); stdOutForSuite.str(""); stdErrForSuite.str(""); unexpectedExceptions = 0; CumulativeReporterBase::testGroupStarting( groupInfo ); } virtual void testCaseStarting( TestCaseInfo const& testCaseInfo ) CATCH_OVERRIDE { m_okToFail = testCaseInfo.okToFail(); } virtual bool assertionEnded( AssertionStats const& assertionStats ) CATCH_OVERRIDE { if( assertionStats.assertionResult.getResultType() == ResultWas::ThrewException && !m_okToFail ) unexpectedExceptions++; return CumulativeReporterBase::assertionEnded( assertionStats ); } virtual void testCaseEnded( TestCaseStats const& testCaseStats ) CATCH_OVERRIDE { stdOutForSuite << testCaseStats.stdOut; stdErrForSuite << testCaseStats.stdErr; CumulativeReporterBase::testCaseEnded( testCaseStats ); } virtual void testGroupEnded( TestGroupStats const& testGroupStats ) CATCH_OVERRIDE { double suiteTime = suiteTimer.getElapsedSeconds(); CumulativeReporterBase::testGroupEnded( testGroupStats ); writeGroup( *m_testGroups.back(), suiteTime ); } virtual void testRunEndedCumulative() CATCH_OVERRIDE { xml.endElement(); } void writeGroup( TestGroupNode const& groupNode, double suiteTime ) { XmlWriter::ScopedElement e = xml.scopedElement( "testsuite" ); TestGroupStats const& stats = groupNode.value; xml.writeAttribute( "name", stats.groupInfo.name ); xml.writeAttribute( "errors", unexpectedExceptions ); xml.writeAttribute( "failures", stats.totals.assertions.failed-unexpectedExceptions ); xml.writeAttribute( "tests", stats.totals.assertions.total() ); xml.writeAttribute( "hostname", "tbd" ); // !TBD if( m_config->showDurations() == ShowDurations::Never ) xml.writeAttribute( "time", "" ); else xml.writeAttribute( "time", suiteTime ); xml.writeAttribute( "timestamp", getCurrentTimestamp() ); // Write test cases for( TestGroupNode::ChildNodes::const_iterator it = groupNode.children.begin(), itEnd = groupNode.children.end(); it != itEnd; ++it ) writeTestCase( **it ); xml.scopedElement( "system-out" ).writeText( trim( stdOutForSuite.str() ), false ); xml.scopedElement( "system-err" ).writeText( trim( stdErrForSuite.str() ), false ); } void writeTestCase( TestCaseNode const& testCaseNode ) { TestCaseStats const& stats = testCaseNode.value; // All test cases have exactly one section - which represents the // test case itself. That section may have 0-n nested sections assert( testCaseNode.children.size() == 1 ); SectionNode const& rootSection = *testCaseNode.children.front(); std::string className = stats.testInfo.className; if( className.empty() ) { if( rootSection.childSections.empty() ) className = "global"; } writeSection( className, "", rootSection ); } void writeSection( std::string const& className, std::string const& rootName, SectionNode const& sectionNode ) { std::string name = trim( sectionNode.stats.sectionInfo.name ); if( !rootName.empty() ) name = rootName + '/' + name; if( !sectionNode.assertions.empty() || !sectionNode.stdOut.empty() || !sectionNode.stdErr.empty() ) { XmlWriter::ScopedElement e = xml.scopedElement( "testcase" ); if( className.empty() ) { xml.writeAttribute( "classname", name ); xml.writeAttribute( "name", "root" ); } else { xml.writeAttribute( "classname", className ); xml.writeAttribute( "name", name ); } xml.writeAttribute( "time", Catch::toString( sectionNode.stats.durationInSeconds ) ); writeAssertions( sectionNode ); if( !sectionNode.stdOut.empty() ) xml.scopedElement( "system-out" ).writeText( trim( sectionNode.stdOut ), false ); if( !sectionNode.stdErr.empty() ) xml.scopedElement( "system-err" ).writeText( trim( sectionNode.stdErr ), false ); } for( SectionNode::ChildSections::const_iterator it = sectionNode.childSections.begin(), itEnd = sectionNode.childSections.end(); it != itEnd; ++it ) if( className.empty() ) writeSection( name, "", **it ); else writeSection( className, name, **it ); } void writeAssertions( SectionNode const& sectionNode ) { for( SectionNode::Assertions::const_iterator it = sectionNode.assertions.begin(), itEnd = sectionNode.assertions.end(); it != itEnd; ++it ) writeAssertion( *it ); } void writeAssertion( AssertionStats const& stats ) { AssertionResult const& result = stats.assertionResult; if( !result.isOk() ) { std::string elementName; switch( result.getResultType() ) { case ResultWas::ThrewException: case ResultWas::FatalErrorCondition: elementName = "error"; break; case ResultWas::ExplicitFailure: elementName = "failure"; break; case ResultWas::ExpressionFailed: elementName = "failure"; break; case ResultWas::DidntThrowException: elementName = "failure"; break; // We should never see these here: case ResultWas::Info: case ResultWas::Warning: case ResultWas::Ok: case ResultWas::Unknown: case ResultWas::FailureBit: case ResultWas::Exception: elementName = "internalError"; break; } XmlWriter::ScopedElement e = xml.scopedElement( elementName ); xml.writeAttribute( "message", result.getExpandedExpression() ); xml.writeAttribute( "type", result.getTestMacroName() ); std::ostringstream oss; if( !result.getMessage().empty() ) oss << result.getMessage() << '\n'; for( std::vector::const_iterator it = stats.infoMessages.begin(), itEnd = stats.infoMessages.end(); it != itEnd; ++it ) if( it->type == ResultWas::Info ) oss << it->message << '\n'; oss << "at " << result.getSourceInfo(); xml.writeText( oss.str(), false ); } } XmlWriter xml; Timer suiteTimer; std::ostringstream stdOutForSuite; std::ostringstream stdErrForSuite; unsigned int unexpectedExceptions; bool m_okToFail; }; INTERNAL_CATCH_REGISTER_REPORTER( "junit", JunitReporter ) } // end namespace Catch // #included from: ../reporters/catch_reporter_console.hpp #define TWOBLUECUBES_CATCH_REPORTER_CONSOLE_HPP_INCLUDED #include #include namespace Catch { struct ConsoleReporter : StreamingReporterBase { ConsoleReporter( ReporterConfig const& _config ) : StreamingReporterBase( _config ), m_headerPrinted( false ) {} virtual ~ConsoleReporter() CATCH_OVERRIDE; static std::string getDescription() { return "Reports test results as plain lines of text"; } virtual void noMatchingTestCases( std::string const& spec ) CATCH_OVERRIDE { stream << "No test cases matched '" << spec << '\'' << std::endl; } virtual void assertionStarting( AssertionInfo const& ) CATCH_OVERRIDE { } virtual bool assertionEnded( AssertionStats const& _assertionStats ) CATCH_OVERRIDE { AssertionResult const& result = _assertionStats.assertionResult; bool includeResults = m_config->includeSuccessfulResults() || !result.isOk(); // Drop out if result was successful but we're not printing them. if( !includeResults && result.getResultType() != ResultWas::Warning ) return false; lazyPrint(); AssertionPrinter printer( stream, _assertionStats, includeResults ); printer.print(); stream << std::endl; return true; } virtual void sectionStarting( SectionInfo const& _sectionInfo ) CATCH_OVERRIDE { m_headerPrinted = false; StreamingReporterBase::sectionStarting( _sectionInfo ); } virtual void sectionEnded( SectionStats const& _sectionStats ) CATCH_OVERRIDE { if( _sectionStats.missingAssertions ) { lazyPrint(); Colour colour( Colour::ResultError ); if( m_sectionStack.size() > 1 ) stream << "\nNo assertions in section"; else stream << "\nNo assertions in test case"; stream << " '" << _sectionStats.sectionInfo.name << "'\n" << std::endl; } if( m_config->showDurations() == ShowDurations::Always ) { stream << getFormattedDuration(_sectionStats.durationInSeconds) << " s: " << _sectionStats.sectionInfo.name << std::endl; } if( m_headerPrinted ) { m_headerPrinted = false; } StreamingReporterBase::sectionEnded( _sectionStats ); } virtual void testCaseEnded( TestCaseStats const& _testCaseStats ) CATCH_OVERRIDE { StreamingReporterBase::testCaseEnded( _testCaseStats ); m_headerPrinted = false; } virtual void testGroupEnded( TestGroupStats const& _testGroupStats ) CATCH_OVERRIDE { if( currentGroupInfo.used ) { printSummaryDivider(); stream << "Summary for group '" << _testGroupStats.groupInfo.name << "':\n"; printTotals( _testGroupStats.totals ); stream << '\n' << std::endl; } StreamingReporterBase::testGroupEnded( _testGroupStats ); } virtual void testRunEnded( TestRunStats const& _testRunStats ) CATCH_OVERRIDE { printTotalsDivider( _testRunStats.totals ); printTotals( _testRunStats.totals ); stream << std::endl; StreamingReporterBase::testRunEnded( _testRunStats ); } private: class AssertionPrinter { void operator= ( AssertionPrinter const& ); public: AssertionPrinter( std::ostream& _stream, AssertionStats const& _stats, bool _printInfoMessages ) : stream( _stream ), stats( _stats ), result( _stats.assertionResult ), colour( Colour::None ), message( result.getMessage() ), messages( _stats.infoMessages ), printInfoMessages( _printInfoMessages ) { switch( result.getResultType() ) { case ResultWas::Ok: colour = Colour::Success; passOrFail = "PASSED"; //if( result.hasMessage() ) if( _stats.infoMessages.size() == 1 ) messageLabel = "with message"; if( _stats.infoMessages.size() > 1 ) messageLabel = "with messages"; break; case ResultWas::ExpressionFailed: if( result.isOk() ) { colour = Colour::Success; passOrFail = "FAILED - but was ok"; } else { colour = Colour::Error; passOrFail = "FAILED"; } if( _stats.infoMessages.size() == 1 ) messageLabel = "with message"; if( _stats.infoMessages.size() > 1 ) messageLabel = "with messages"; break; case ResultWas::ThrewException: colour = Colour::Error; passOrFail = "FAILED"; messageLabel = "due to unexpected exception with "; if (_stats.infoMessages.size() == 1) messageLabel += "message"; if (_stats.infoMessages.size() > 1) messageLabel += "messages"; break; case ResultWas::FatalErrorCondition: colour = Colour::Error; passOrFail = "FAILED"; messageLabel = "due to a fatal error condition"; break; case ResultWas::DidntThrowException: colour = Colour::Error; passOrFail = "FAILED"; messageLabel = "because no exception was thrown where one was expected"; break; case ResultWas::Info: messageLabel = "info"; break; case ResultWas::Warning: messageLabel = "warning"; break; case ResultWas::ExplicitFailure: passOrFail = "FAILED"; colour = Colour::Error; if( _stats.infoMessages.size() == 1 ) messageLabel = "explicitly with message"; if( _stats.infoMessages.size() > 1 ) messageLabel = "explicitly with messages"; break; // These cases are here to prevent compiler warnings case ResultWas::Unknown: case ResultWas::FailureBit: case ResultWas::Exception: passOrFail = "** internal error **"; colour = Colour::Error; break; } } void print() const { printSourceInfo(); if( stats.totals.assertions.total() > 0 ) { if( result.isOk() ) stream << '\n'; printResultType(); printOriginalExpression(); printReconstructedExpression(); } else { stream << '\n'; } printMessage(); } private: void printResultType() const { if( !passOrFail.empty() ) { Colour colourGuard( colour ); stream << passOrFail << ":\n"; } } void printOriginalExpression() const { if( result.hasExpression() ) { Colour colourGuard( Colour::OriginalExpression ); stream << " "; stream << result.getExpressionInMacro(); stream << '\n'; } } void printReconstructedExpression() const { if( result.hasExpandedExpression() ) { stream << "with expansion:\n"; Colour colourGuard( Colour::ReconstructedExpression ); stream << Text( result.getExpandedExpression(), TextAttributes().setIndent(2) ) << '\n'; } } void printMessage() const { if( !messageLabel.empty() ) stream << messageLabel << ':' << '\n'; for( std::vector::const_iterator it = messages.begin(), itEnd = messages.end(); it != itEnd; ++it ) { // If this assertion is a warning ignore any INFO messages if( printInfoMessages || it->type != ResultWas::Info ) stream << Text( it->message, TextAttributes().setIndent(2) ) << '\n'; } } void printSourceInfo() const { Colour colourGuard( Colour::FileName ); stream << result.getSourceInfo() << ": "; } std::ostream& stream; AssertionStats const& stats; AssertionResult const& result; Colour::Code colour; std::string passOrFail; std::string messageLabel; std::string message; std::vector messages; bool printInfoMessages; }; void lazyPrint() { if( !currentTestRunInfo.used ) lazyPrintRunInfo(); if( !currentGroupInfo.used ) lazyPrintGroupInfo(); if( !m_headerPrinted ) { printTestCaseAndSectionHeader(); m_headerPrinted = true; } } void lazyPrintRunInfo() { stream << '\n' << getLineOfChars<'~'>() << '\n'; Colour colour( Colour::SecondaryText ); stream << currentTestRunInfo->name << " is a Catch v" << libraryVersion() << " host application.\n" << "Run with -? for options\n\n"; if( m_config->rngSeed() != 0 ) stream << "Randomness seeded to: " << m_config->rngSeed() << "\n\n"; currentTestRunInfo.used = true; } void lazyPrintGroupInfo() { if( !currentGroupInfo->name.empty() && currentGroupInfo->groupsCounts > 1 ) { printClosedHeader( "Group: " + currentGroupInfo->name ); currentGroupInfo.used = true; } } void printTestCaseAndSectionHeader() { assert( !m_sectionStack.empty() ); printOpenHeader( currentTestCaseInfo->name ); if( m_sectionStack.size() > 1 ) { Colour colourGuard( Colour::Headers ); std::vector::const_iterator it = m_sectionStack.begin()+1, // Skip first section (test case) itEnd = m_sectionStack.end(); for( ; it != itEnd; ++it ) printHeaderString( it->name, 2 ); } SourceLineInfo lineInfo = m_sectionStack.back().lineInfo; if( !lineInfo.empty() ){ stream << getLineOfChars<'-'>() << '\n'; Colour colourGuard( Colour::FileName ); stream << lineInfo << '\n'; } stream << getLineOfChars<'.'>() << '\n' << std::endl; } void printClosedHeader( std::string const& _name ) { printOpenHeader( _name ); stream << getLineOfChars<'.'>() << '\n'; } void printOpenHeader( std::string const& _name ) { stream << getLineOfChars<'-'>() << '\n'; { Colour colourGuard( Colour::Headers ); printHeaderString( _name ); } } // if string has a : in first line will set indent to follow it on // subsequent lines void printHeaderString( std::string const& _string, std::size_t indent = 0 ) { std::size_t i = _string.find( ": " ); if( i != std::string::npos ) i+=2; else i = 0; stream << Text( _string, TextAttributes() .setIndent( indent+i) .setInitialIndent( indent ) ) << '\n'; } struct SummaryColumn { SummaryColumn( std::string const& _label, Colour::Code _colour ) : label( _label ), colour( _colour ) {} SummaryColumn addRow( std::size_t count ) { std::ostringstream oss; oss << count; std::string row = oss.str(); for( std::vector::iterator it = rows.begin(); it != rows.end(); ++it ) { while( it->size() < row.size() ) *it = ' ' + *it; while( it->size() > row.size() ) row = ' ' + row; } rows.push_back( row ); return *this; } std::string label; Colour::Code colour; std::vector rows; }; void printTotals( Totals const& totals ) { if( totals.testCases.total() == 0 ) { stream << Colour( Colour::Warning ) << "No tests ran\n"; } else if( totals.assertions.total() > 0 && totals.testCases.allPassed() ) { stream << Colour( Colour::ResultSuccess ) << "All tests passed"; stream << " (" << pluralise( totals.assertions.passed, "assertion" ) << " in " << pluralise( totals.testCases.passed, "test case" ) << ')' << '\n'; } else { std::vector columns; columns.push_back( SummaryColumn( "", Colour::None ) .addRow( totals.testCases.total() ) .addRow( totals.assertions.total() ) ); columns.push_back( SummaryColumn( "passed", Colour::Success ) .addRow( totals.testCases.passed ) .addRow( totals.assertions.passed ) ); columns.push_back( SummaryColumn( "failed", Colour::ResultError ) .addRow( totals.testCases.failed ) .addRow( totals.assertions.failed ) ); columns.push_back( SummaryColumn( "failed as expected", Colour::ResultExpectedFailure ) .addRow( totals.testCases.failedButOk ) .addRow( totals.assertions.failedButOk ) ); printSummaryRow( "test cases", columns, 0 ); printSummaryRow( "assertions", columns, 1 ); } } void printSummaryRow( std::string const& label, std::vector const& cols, std::size_t row ) { for( std::vector::const_iterator it = cols.begin(); it != cols.end(); ++it ) { std::string value = it->rows[row]; if( it->label.empty() ) { stream << label << ": "; if( value != "0" ) stream << value; else stream << Colour( Colour::Warning ) << "- none -"; } else if( value != "0" ) { stream << Colour( Colour::LightGrey ) << " | "; stream << Colour( it->colour ) << value << ' ' << it->label; } } stream << '\n'; } static std::size_t makeRatio( std::size_t number, std::size_t total ) { std::size_t ratio = total > 0 ? CATCH_CONFIG_CONSOLE_WIDTH * number/ total : 0; return ( ratio == 0 && number > 0 ) ? 1 : ratio; } static std::size_t& findMax( std::size_t& i, std::size_t& j, std::size_t& k ) { if( i > j && i > k ) return i; else if( j > k ) return j; else return k; } void printTotalsDivider( Totals const& totals ) { if( totals.testCases.total() > 0 ) { std::size_t failedRatio = makeRatio( totals.testCases.failed, totals.testCases.total() ); std::size_t failedButOkRatio = makeRatio( totals.testCases.failedButOk, totals.testCases.total() ); std::size_t passedRatio = makeRatio( totals.testCases.passed, totals.testCases.total() ); while( failedRatio + failedButOkRatio + passedRatio < CATCH_CONFIG_CONSOLE_WIDTH-1 ) findMax( failedRatio, failedButOkRatio, passedRatio )++; while( failedRatio + failedButOkRatio + passedRatio > CATCH_CONFIG_CONSOLE_WIDTH-1 ) findMax( failedRatio, failedButOkRatio, passedRatio )--; stream << Colour( Colour::Error ) << std::string( failedRatio, '=' ); stream << Colour( Colour::ResultExpectedFailure ) << std::string( failedButOkRatio, '=' ); if( totals.testCases.allPassed() ) stream << Colour( Colour::ResultSuccess ) << std::string( passedRatio, '=' ); else stream << Colour( Colour::Success ) << std::string( passedRatio, '=' ); } else { stream << Colour( Colour::Warning ) << std::string( CATCH_CONFIG_CONSOLE_WIDTH-1, '=' ); } stream << '\n'; } void printSummaryDivider() { stream << getLineOfChars<'-'>() << '\n'; } private: bool m_headerPrinted; }; INTERNAL_CATCH_REGISTER_REPORTER( "console", ConsoleReporter ) } // end namespace Catch // #included from: ../reporters/catch_reporter_compact.hpp #define TWOBLUECUBES_CATCH_REPORTER_COMPACT_HPP_INCLUDED namespace Catch { struct CompactReporter : StreamingReporterBase { CompactReporter( ReporterConfig const& _config ) : StreamingReporterBase( _config ) {} virtual ~CompactReporter(); static std::string getDescription() { return "Reports test results on a single line, suitable for IDEs"; } virtual ReporterPreferences getPreferences() const { ReporterPreferences prefs; prefs.shouldRedirectStdOut = false; return prefs; } virtual void noMatchingTestCases( std::string const& spec ) { stream << "No test cases matched '" << spec << '\'' << std::endl; } virtual void assertionStarting( AssertionInfo const& ) {} virtual bool assertionEnded( AssertionStats const& _assertionStats ) { AssertionResult const& result = _assertionStats.assertionResult; bool printInfoMessages = true; // Drop out if result was successful and we're not printing those if( !m_config->includeSuccessfulResults() && result.isOk() ) { if( result.getResultType() != ResultWas::Warning ) return false; printInfoMessages = false; } AssertionPrinter printer( stream, _assertionStats, printInfoMessages ); printer.print(); stream << std::endl; return true; } virtual void sectionEnded(SectionStats const& _sectionStats) CATCH_OVERRIDE { if (m_config->showDurations() == ShowDurations::Always) { stream << getFormattedDuration(_sectionStats.durationInSeconds) << " s: " << _sectionStats.sectionInfo.name << std::endl; } } virtual void testRunEnded( TestRunStats const& _testRunStats ) { printTotals( _testRunStats.totals ); stream << '\n' << std::endl; StreamingReporterBase::testRunEnded( _testRunStats ); } private: class AssertionPrinter { void operator= ( AssertionPrinter const& ); public: AssertionPrinter( std::ostream& _stream, AssertionStats const& _stats, bool _printInfoMessages ) : stream( _stream ) , stats( _stats ) , result( _stats.assertionResult ) , messages( _stats.infoMessages ) , itMessage( _stats.infoMessages.begin() ) , printInfoMessages( _printInfoMessages ) {} void print() { printSourceInfo(); itMessage = messages.begin(); switch( result.getResultType() ) { case ResultWas::Ok: printResultType( Colour::ResultSuccess, passedString() ); printOriginalExpression(); printReconstructedExpression(); if ( ! result.hasExpression() ) printRemainingMessages( Colour::None ); else printRemainingMessages(); break; case ResultWas::ExpressionFailed: if( result.isOk() ) printResultType( Colour::ResultSuccess, failedString() + std::string( " - but was ok" ) ); else printResultType( Colour::Error, failedString() ); printOriginalExpression(); printReconstructedExpression(); printRemainingMessages(); break; case ResultWas::ThrewException: printResultType( Colour::Error, failedString() ); printIssue( "unexpected exception with message:" ); printMessage(); printExpressionWas(); printRemainingMessages(); break; case ResultWas::FatalErrorCondition: printResultType( Colour::Error, failedString() ); printIssue( "fatal error condition with message:" ); printMessage(); printExpressionWas(); printRemainingMessages(); break; case ResultWas::DidntThrowException: printResultType( Colour::Error, failedString() ); printIssue( "expected exception, got none" ); printExpressionWas(); printRemainingMessages(); break; case ResultWas::Info: printResultType( Colour::None, "info" ); printMessage(); printRemainingMessages(); break; case ResultWas::Warning: printResultType( Colour::None, "warning" ); printMessage(); printRemainingMessages(); break; case ResultWas::ExplicitFailure: printResultType( Colour::Error, failedString() ); printIssue( "explicitly" ); printRemainingMessages( Colour::None ); break; // These cases are here to prevent compiler warnings case ResultWas::Unknown: case ResultWas::FailureBit: case ResultWas::Exception: printResultType( Colour::Error, "** internal error **" ); break; } } private: // Colour::LightGrey static Colour::Code dimColour() { return Colour::FileName; } #ifdef CATCH_PLATFORM_MAC static const char* failedString() { return "FAILED"; } static const char* passedString() { return "PASSED"; } #else static const char* failedString() { return "failed"; } static const char* passedString() { return "passed"; } #endif void printSourceInfo() const { Colour colourGuard( Colour::FileName ); stream << result.getSourceInfo() << ':'; } void printResultType( Colour::Code colour, std::string const& passOrFail ) const { if( !passOrFail.empty() ) { { Colour colourGuard( colour ); stream << ' ' << passOrFail; } stream << ':'; } } void printIssue( std::string const& issue ) const { stream << ' ' << issue; } void printExpressionWas() { if( result.hasExpression() ) { stream << ';'; { Colour colour( dimColour() ); stream << " expression was:"; } printOriginalExpression(); } } void printOriginalExpression() const { if( result.hasExpression() ) { stream << ' ' << result.getExpression(); } } void printReconstructedExpression() const { if( result.hasExpandedExpression() ) { { Colour colour( dimColour() ); stream << " for: "; } stream << result.getExpandedExpression(); } } void printMessage() { if ( itMessage != messages.end() ) { stream << " '" << itMessage->message << '\''; ++itMessage; } } void printRemainingMessages( Colour::Code colour = dimColour() ) { if ( itMessage == messages.end() ) return; // using messages.end() directly yields compilation error: std::vector::const_iterator itEnd = messages.end(); const std::size_t N = static_cast( std::distance( itMessage, itEnd ) ); { Colour colourGuard( colour ); stream << " with " << pluralise( N, "message" ) << ':'; } for(; itMessage != itEnd; ) { // If this assertion is a warning ignore any INFO messages if( printInfoMessages || itMessage->type != ResultWas::Info ) { stream << " '" << itMessage->message << '\''; if ( ++itMessage != itEnd ) { Colour colourGuard( dimColour() ); stream << " and"; } } } } private: std::ostream& stream; AssertionStats const& stats; AssertionResult const& result; std::vector messages; std::vector::const_iterator itMessage; bool printInfoMessages; }; // Colour, message variants: // - white: No tests ran. // - red: Failed [both/all] N test cases, failed [both/all] M assertions. // - white: Passed [both/all] N test cases (no assertions). // - red: Failed N tests cases, failed M assertions. // - green: Passed [both/all] N tests cases with M assertions. std::string bothOrAll( std::size_t count ) const { return count == 1 ? std::string() : count == 2 ? "both " : "all " ; } void printTotals( const Totals& totals ) const { if( totals.testCases.total() == 0 ) { stream << "No tests ran."; } else if( totals.testCases.failed == totals.testCases.total() ) { Colour colour( Colour::ResultError ); const std::string qualify_assertions_failed = totals.assertions.failed == totals.assertions.total() ? bothOrAll( totals.assertions.failed ) : std::string(); stream << "Failed " << bothOrAll( totals.testCases.failed ) << pluralise( totals.testCases.failed, "test case" ) << ", " "failed " << qualify_assertions_failed << pluralise( totals.assertions.failed, "assertion" ) << '.'; } else if( totals.assertions.total() == 0 ) { stream << "Passed " << bothOrAll( totals.testCases.total() ) << pluralise( totals.testCases.total(), "test case" ) << " (no assertions)."; } else if( totals.assertions.failed ) { Colour colour( Colour::ResultError ); stream << "Failed " << pluralise( totals.testCases.failed, "test case" ) << ", " "failed " << pluralise( totals.assertions.failed, "assertion" ) << '.'; } else { Colour colour( Colour::ResultSuccess ); stream << "Passed " << bothOrAll( totals.testCases.passed ) << pluralise( totals.testCases.passed, "test case" ) << " with " << pluralise( totals.assertions.passed, "assertion" ) << '.'; } } }; INTERNAL_CATCH_REGISTER_REPORTER( "compact", CompactReporter ) } // end namespace Catch namespace Catch { // These are all here to avoid warnings about not having any out of line // virtual methods NonCopyable::~NonCopyable() {} IShared::~IShared() {} IStream::~IStream() CATCH_NOEXCEPT {} FileStream::~FileStream() CATCH_NOEXCEPT {} CoutStream::~CoutStream() CATCH_NOEXCEPT {} DebugOutStream::~DebugOutStream() CATCH_NOEXCEPT {} StreamBufBase::~StreamBufBase() CATCH_NOEXCEPT {} IContext::~IContext() {} IResultCapture::~IResultCapture() {} ITestCase::~ITestCase() {} ITestCaseRegistry::~ITestCaseRegistry() {} IRegistryHub::~IRegistryHub() {} IMutableRegistryHub::~IMutableRegistryHub() {} IExceptionTranslator::~IExceptionTranslator() {} IExceptionTranslatorRegistry::~IExceptionTranslatorRegistry() {} IReporter::~IReporter() {} IReporterFactory::~IReporterFactory() {} IReporterRegistry::~IReporterRegistry() {} IStreamingReporter::~IStreamingReporter() {} AssertionStats::~AssertionStats() {} SectionStats::~SectionStats() {} TestCaseStats::~TestCaseStats() {} TestGroupStats::~TestGroupStats() {} TestRunStats::~TestRunStats() {} CumulativeReporterBase::SectionNode::~SectionNode() {} CumulativeReporterBase::~CumulativeReporterBase() {} StreamingReporterBase::~StreamingReporterBase() {} ConsoleReporter::~ConsoleReporter() {} CompactReporter::~CompactReporter() {} IRunner::~IRunner() {} IMutableContext::~IMutableContext() {} IConfig::~IConfig() {} XmlReporter::~XmlReporter() {} JunitReporter::~JunitReporter() {} TestRegistry::~TestRegistry() {} FreeFunctionTestCase::~FreeFunctionTestCase() {} IGeneratorInfo::~IGeneratorInfo() {} IGeneratorsForTest::~IGeneratorsForTest() {} WildcardPattern::~WildcardPattern() {} TestSpec::Pattern::~Pattern() {} TestSpec::NamePattern::~NamePattern() {} TestSpec::TagPattern::~TagPattern() {} TestSpec::ExcludedPattern::~ExcludedPattern() {} Matchers::Impl::MatcherUntypedBase::~MatcherUntypedBase() {} void Config::dummy() {} namespace TestCaseTracking { ITracker::~ITracker() {} TrackerBase::~TrackerBase() {} SectionTracker::~SectionTracker() {} IndexTracker::~IndexTracker() {} } } #ifdef __clang__ #pragma clang diagnostic pop #endif #endif #ifdef CATCH_CONFIG_MAIN // #included from: internal/catch_default_main.hpp #define TWOBLUECUBES_CATCH_DEFAULT_MAIN_HPP_INCLUDED #ifndef __OBJC__ #if defined(WIN32) && defined(_UNICODE) && !defined(DO_NOT_USE_WMAIN) // Standard C/C++ Win32 Unicode wmain entry point extern "C" int wmain (int argc, wchar_t * argv[], wchar_t * []) { #else // Standard C/C++ main entry point int main (int argc, char * argv[]) { #endif int result = Catch::Session().run( argc, argv ); return ( result < 0xff ? result : 0xff ); } #else // __OBJC__ // Objective-C entry point int main (int argc, char * const argv[]) { #if !CATCH_ARC_ENABLED NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; #endif Catch::registerTestMethods(); int result = Catch::Session().run( argc, (char* const*)argv ); #if !CATCH_ARC_ENABLED [pool drain]; #endif return ( result < 0xff ? result : 0xff ); } #endif // __OBJC__ #endif #ifdef CLARA_CONFIG_MAIN_NOT_DEFINED # undef CLARA_CONFIG_MAIN #endif ////// // If this config identifier is defined then all CATCH macros are prefixed with CATCH_ #ifdef CATCH_CONFIG_PREFIX_ALL #if defined(CATCH_CONFIG_FAST_COMPILE) #define CATCH_REQUIRE( expr ) INTERNAL_CATCH_TEST_NO_TRY( "CATCH_REQUIRE", Catch::ResultDisposition::Normal, expr ) #define CATCH_REQUIRE_FALSE( expr ) INTERNAL_CATCH_TEST_NO_TRY( "CATCH_REQUIRE_FALSE", Catch::ResultDisposition::Normal | Catch::ResultDisposition::FalseTest, expr ) #else #define CATCH_REQUIRE( expr ) INTERNAL_CATCH_TEST( "CATCH_REQUIRE", Catch::ResultDisposition::Normal, expr ) #define CATCH_REQUIRE_FALSE( expr ) INTERNAL_CATCH_TEST( "CATCH_REQUIRE_FALSE", Catch::ResultDisposition::Normal | Catch::ResultDisposition::FalseTest, expr ) #endif #define CATCH_REQUIRE_THROWS( expr ) INTERNAL_CATCH_THROWS( "CATCH_REQUIRE_THROWS", Catch::ResultDisposition::Normal, "", expr ) #define CATCH_REQUIRE_THROWS_AS( expr, exceptionType ) INTERNAL_CATCH_THROWS_AS( "CATCH_REQUIRE_THROWS_AS", exceptionType, Catch::ResultDisposition::Normal, expr ) #define CATCH_REQUIRE_THROWS_WITH( expr, matcher ) INTERNAL_CATCH_THROWS( "CATCH_REQUIRE_THROWS_WITH", Catch::ResultDisposition::Normal, matcher, expr ) #define CATCH_REQUIRE_NOTHROW( expr ) INTERNAL_CATCH_NO_THROW( "CATCH_REQUIRE_NOTHROW", Catch::ResultDisposition::Normal, expr ) #define CATCH_CHECK( expr ) INTERNAL_CATCH_TEST( "CATCH_CHECK", Catch::ResultDisposition::ContinueOnFailure, expr ) #define CATCH_CHECK_FALSE( expr ) INTERNAL_CATCH_TEST( "CATCH_CHECK_FALSE", Catch::ResultDisposition::ContinueOnFailure | Catch::ResultDisposition::FalseTest, expr ) #define CATCH_CHECKED_IF( expr ) INTERNAL_CATCH_IF( "CATCH_CHECKED_IF", Catch::ResultDisposition::ContinueOnFailure, expr ) #define CATCH_CHECKED_ELSE( expr ) INTERNAL_CATCH_ELSE( "CATCH_CHECKED_ELSE", Catch::ResultDisposition::ContinueOnFailure, expr ) #define CATCH_CHECK_NOFAIL( expr ) INTERNAL_CATCH_TEST( "CATCH_CHECK_NOFAIL", Catch::ResultDisposition::ContinueOnFailure | Catch::ResultDisposition::SuppressFail, expr ) #define CATCH_CHECK_THROWS( expr ) INTERNAL_CATCH_THROWS( "CATCH_CHECK_THROWS", Catch::ResultDisposition::ContinueOnFailure, "", expr ) #define CATCH_CHECK_THROWS_AS( expr, exceptionType ) INTERNAL_CATCH_THROWS_AS( "CATCH_CHECK_THROWS_AS", exceptionType, Catch::ResultDisposition::ContinueOnFailure, expr ) #define CATCH_CHECK_THROWS_WITH( expr, matcher ) INTERNAL_CATCH_THROWS( "CATCH_CHECK_THROWS_WITH", Catch::ResultDisposition::ContinueOnFailure, matcher, expr ) #define CATCH_CHECK_NOTHROW( expr ) INTERNAL_CATCH_NO_THROW( "CATCH_CHECK_NOTHROW", Catch::ResultDisposition::ContinueOnFailure, expr ) #define CATCH_CHECK_THAT( arg, matcher ) INTERNAL_CHECK_THAT( "CATCH_CHECK_THAT", matcher, Catch::ResultDisposition::ContinueOnFailure, arg ) #if defined(CATCH_CONFIG_FAST_COMPILE) #define CATCH_REQUIRE_THAT( arg, matcher ) INTERNAL_CHECK_THAT_NO_TRY( "CATCH_REQUIRE_THAT", matcher, Catch::ResultDisposition::Normal, arg ) #else #define CATCH_REQUIRE_THAT( arg, matcher ) INTERNAL_CHECK_THAT( "CATCH_REQUIRE_THAT", matcher, Catch::ResultDisposition::Normal, arg ) #endif #define CATCH_INFO( msg ) INTERNAL_CATCH_INFO( "CATCH_INFO", msg ) #define CATCH_WARN( msg ) INTERNAL_CATCH_MSG( "CATCH_WARN", Catch::ResultWas::Warning, Catch::ResultDisposition::ContinueOnFailure, msg ) #define CATCH_SCOPED_INFO( msg ) INTERNAL_CATCH_INFO( "CATCH_INFO", msg ) #define CATCH_CAPTURE( msg ) INTERNAL_CATCH_INFO( "CATCH_CAPTURE", #msg " := " << Catch::toString(msg) ) #define CATCH_SCOPED_CAPTURE( msg ) INTERNAL_CATCH_INFO( "CATCH_CAPTURE", #msg " := " << Catch::toString(msg) ) #ifdef CATCH_CONFIG_VARIADIC_MACROS #define CATCH_TEST_CASE( ... ) INTERNAL_CATCH_TESTCASE( __VA_ARGS__ ) #define CATCH_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TEST_CASE_METHOD( className, __VA_ARGS__ ) #define CATCH_METHOD_AS_TEST_CASE( method, ... ) INTERNAL_CATCH_METHOD_AS_TEST_CASE( method, __VA_ARGS__ ) #define CATCH_REGISTER_TEST_CASE( Function, ... ) INTERNAL_CATCH_REGISTER_TESTCASE( Function, __VA_ARGS__ ) #define CATCH_SECTION( ... ) INTERNAL_CATCH_SECTION( __VA_ARGS__ ) #define CATCH_FAIL( ... ) INTERNAL_CATCH_MSG( "CATCH_FAIL", Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::Normal, __VA_ARGS__ ) #define CATCH_FAIL_CHECK( ... ) INTERNAL_CATCH_MSG( "CATCH_FAIL_CHECK", Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ ) #define CATCH_SUCCEED( ... ) INTERNAL_CATCH_MSG( "CATCH_SUCCEED", Catch::ResultWas::Ok, Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ ) #else #define CATCH_TEST_CASE( name, description ) INTERNAL_CATCH_TESTCASE( name, description ) #define CATCH_TEST_CASE_METHOD( className, name, description ) INTERNAL_CATCH_TEST_CASE_METHOD( className, name, description ) #define CATCH_METHOD_AS_TEST_CASE( method, name, description ) INTERNAL_CATCH_METHOD_AS_TEST_CASE( method, name, description ) #define CATCH_REGISTER_TEST_CASE( function, name, description ) INTERNAL_CATCH_REGISTER_TESTCASE( function, name, description ) #define CATCH_SECTION( name, description ) INTERNAL_CATCH_SECTION( name, description ) #define CATCH_FAIL( msg ) INTERNAL_CATCH_MSG( "CATCH_FAIL", Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::Normal, msg ) #define CATCH_FAIL_CHECK( msg ) INTERNAL_CATCH_MSG( "CATCH_FAIL_CHECK", Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::ContinueOnFailure, msg ) #define CATCH_SUCCEED( msg ) INTERNAL_CATCH_MSG( "CATCH_SUCCEED", Catch::ResultWas::Ok, Catch::ResultDisposition::ContinueOnFailure, msg ) #endif #define CATCH_ANON_TEST_CASE() INTERNAL_CATCH_TESTCASE( "", "" ) #define CATCH_REGISTER_REPORTER( name, reporterType ) INTERNAL_CATCH_REGISTER_REPORTER( name, reporterType ) #define CATCH_REGISTER_LEGACY_REPORTER( name, reporterType ) INTERNAL_CATCH_REGISTER_LEGACY_REPORTER( name, reporterType ) #define CATCH_GENERATE( expr) INTERNAL_CATCH_GENERATE( expr ) // "BDD-style" convenience wrappers #ifdef CATCH_CONFIG_VARIADIC_MACROS #define CATCH_SCENARIO( ... ) CATCH_TEST_CASE( "Scenario: " __VA_ARGS__ ) #define CATCH_SCENARIO_METHOD( className, ... ) INTERNAL_CATCH_TEST_CASE_METHOD( className, "Scenario: " __VA_ARGS__ ) #else #define CATCH_SCENARIO( name, tags ) CATCH_TEST_CASE( "Scenario: " name, tags ) #define CATCH_SCENARIO_METHOD( className, name, tags ) INTERNAL_CATCH_TEST_CASE_METHOD( className, "Scenario: " name, tags ) #endif #define CATCH_GIVEN( desc ) CATCH_SECTION( std::string( "Given: ") + desc, "" ) #define CATCH_WHEN( desc ) CATCH_SECTION( std::string( " When: ") + desc, "" ) #define CATCH_AND_WHEN( desc ) CATCH_SECTION( std::string( " And: ") + desc, "" ) #define CATCH_THEN( desc ) CATCH_SECTION( std::string( " Then: ") + desc, "" ) #define CATCH_AND_THEN( desc ) CATCH_SECTION( std::string( " And: ") + desc, "" ) // If CATCH_CONFIG_PREFIX_ALL is not defined then the CATCH_ prefix is not required #else #if defined(CATCH_CONFIG_FAST_COMPILE) #define REQUIRE( expr ) INTERNAL_CATCH_TEST_NO_TRY( "REQUIRE", Catch::ResultDisposition::Normal, expr ) #define REQUIRE_FALSE( expr ) INTERNAL_CATCH_TEST_NO_TRY( "REQUIRE_FALSE", Catch::ResultDisposition::Normal | Catch::ResultDisposition::FalseTest, expr ) #else #define REQUIRE( expr ) INTERNAL_CATCH_TEST( "REQUIRE", Catch::ResultDisposition::Normal, expr ) #define REQUIRE_FALSE( expr ) INTERNAL_CATCH_TEST( "REQUIRE_FALSE", Catch::ResultDisposition::Normal | Catch::ResultDisposition::FalseTest, expr ) #endif #define REQUIRE_THROWS( expr ) INTERNAL_CATCH_THROWS( "REQUIRE_THROWS", Catch::ResultDisposition::Normal, "", expr ) #define REQUIRE_THROWS_AS( expr, exceptionType ) INTERNAL_CATCH_THROWS_AS( "REQUIRE_THROWS_AS", exceptionType, Catch::ResultDisposition::Normal, expr ) #define REQUIRE_THROWS_WITH( expr, matcher ) INTERNAL_CATCH_THROWS( "REQUIRE_THROWS_WITH", Catch::ResultDisposition::Normal, matcher, expr ) #define REQUIRE_NOTHROW( expr ) INTERNAL_CATCH_NO_THROW( "REQUIRE_NOTHROW", Catch::ResultDisposition::Normal, expr ) #define CHECK( expr ) INTERNAL_CATCH_TEST( "CHECK", Catch::ResultDisposition::ContinueOnFailure, expr ) #define CHECK_FALSE( expr ) INTERNAL_CATCH_TEST( "CHECK_FALSE", Catch::ResultDisposition::ContinueOnFailure | Catch::ResultDisposition::FalseTest, expr ) #define CHECKED_IF( expr ) INTERNAL_CATCH_IF( "CHECKED_IF", Catch::ResultDisposition::ContinueOnFailure, expr ) #define CHECKED_ELSE( expr ) INTERNAL_CATCH_ELSE( "CHECKED_ELSE", Catch::ResultDisposition::ContinueOnFailure, expr ) #define CHECK_NOFAIL( expr ) INTERNAL_CATCH_TEST( "CHECK_NOFAIL", Catch::ResultDisposition::ContinueOnFailure | Catch::ResultDisposition::SuppressFail, expr ) #define CHECK_THROWS( expr ) INTERNAL_CATCH_THROWS( "CHECK_THROWS", Catch::ResultDisposition::ContinueOnFailure, "", expr ) #define CHECK_THROWS_AS( expr, exceptionType ) INTERNAL_CATCH_THROWS_AS( "CHECK_THROWS_AS", exceptionType, Catch::ResultDisposition::ContinueOnFailure, expr ) #define CHECK_THROWS_WITH( expr, matcher ) INTERNAL_CATCH_THROWS( "CHECK_THROWS_WITH", Catch::ResultDisposition::ContinueOnFailure, matcher, expr ) #define CHECK_NOTHROW( expr ) INTERNAL_CATCH_NO_THROW( "CHECK_NOTHROW", Catch::ResultDisposition::ContinueOnFailure, expr ) #define CHECK_THAT( arg, matcher ) INTERNAL_CHECK_THAT( "CHECK_THAT", matcher, Catch::ResultDisposition::ContinueOnFailure, arg ) #if defined(CATCH_CONFIG_FAST_COMPILE) #define REQUIRE_THAT( arg, matcher ) INTERNAL_CHECK_THAT_NO_TRY( "REQUIRE_THAT", matcher, Catch::ResultDisposition::Normal, arg ) #else #define REQUIRE_THAT( arg, matcher ) INTERNAL_CHECK_THAT( "REQUIRE_THAT", matcher, Catch::ResultDisposition::Normal, arg ) #endif #define INFO( msg ) INTERNAL_CATCH_INFO( "INFO", msg ) #define WARN( msg ) INTERNAL_CATCH_MSG( "WARN", Catch::ResultWas::Warning, Catch::ResultDisposition::ContinueOnFailure, msg ) #define SCOPED_INFO( msg ) INTERNAL_CATCH_INFO( "INFO", msg ) #define CAPTURE( msg ) INTERNAL_CATCH_INFO( "CAPTURE", #msg " := " << Catch::toString(msg) ) #define SCOPED_CAPTURE( msg ) INTERNAL_CATCH_INFO( "CAPTURE", #msg " := " << Catch::toString(msg) ) #ifdef CATCH_CONFIG_VARIADIC_MACROS #define TEST_CASE( ... ) INTERNAL_CATCH_TESTCASE( __VA_ARGS__ ) #define TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TEST_CASE_METHOD( className, __VA_ARGS__ ) #define METHOD_AS_TEST_CASE( method, ... ) INTERNAL_CATCH_METHOD_AS_TEST_CASE( method, __VA_ARGS__ ) #define REGISTER_TEST_CASE( Function, ... ) INTERNAL_CATCH_REGISTER_TESTCASE( Function, __VA_ARGS__ ) #define SECTION( ... ) INTERNAL_CATCH_SECTION( __VA_ARGS__ ) #define FAIL( ... ) INTERNAL_CATCH_MSG( "FAIL", Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::Normal, __VA_ARGS__ ) #define FAIL_CHECK( ... ) INTERNAL_CATCH_MSG( "FAIL_CHECK", Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ ) #define SUCCEED( ... ) INTERNAL_CATCH_MSG( "SUCCEED", Catch::ResultWas::Ok, Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ ) #else #define TEST_CASE( name, description ) INTERNAL_CATCH_TESTCASE( name, description ) #define TEST_CASE_METHOD( className, name, description ) INTERNAL_CATCH_TEST_CASE_METHOD( className, name, description ) #define METHOD_AS_TEST_CASE( method, name, description ) INTERNAL_CATCH_METHOD_AS_TEST_CASE( method, name, description ) #define REGISTER_TEST_CASE( method, name, description ) INTERNAL_CATCH_REGISTER_TESTCASE( method, name, description ) #define SECTION( name, description ) INTERNAL_CATCH_SECTION( name, description ) #define FAIL( msg ) INTERNAL_CATCH_MSG( "FAIL", Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::Normal, msg ) #define FAIL_CHECK( msg ) INTERNAL_CATCH_MSG( "FAIL_CHECK", Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::ContinueOnFailure, msg ) #define SUCCEED( msg ) INTERNAL_CATCH_MSG( "SUCCEED", Catch::ResultWas::Ok, Catch::ResultDisposition::ContinueOnFailure, msg ) #endif #define ANON_TEST_CASE() INTERNAL_CATCH_TESTCASE( "", "" ) #define REGISTER_REPORTER( name, reporterType ) INTERNAL_CATCH_REGISTER_REPORTER( name, reporterType ) #define REGISTER_LEGACY_REPORTER( name, reporterType ) INTERNAL_CATCH_REGISTER_LEGACY_REPORTER( name, reporterType ) #define GENERATE( expr) INTERNAL_CATCH_GENERATE( expr ) #endif #define CATCH_TRANSLATE_EXCEPTION( signature ) INTERNAL_CATCH_TRANSLATE_EXCEPTION( signature ) // "BDD-style" convenience wrappers #ifdef CATCH_CONFIG_VARIADIC_MACROS #define SCENARIO( ... ) TEST_CASE( "Scenario: " __VA_ARGS__ ) #define SCENARIO_METHOD( className, ... ) INTERNAL_CATCH_TEST_CASE_METHOD( className, "Scenario: " __VA_ARGS__ ) #else #define SCENARIO( name, tags ) TEST_CASE( "Scenario: " name, tags ) #define SCENARIO_METHOD( className, name, tags ) INTERNAL_CATCH_TEST_CASE_METHOD( className, "Scenario: " name, tags ) #endif #define GIVEN( desc ) SECTION( std::string(" Given: ") + desc, "" ) #define WHEN( desc ) SECTION( std::string(" When: ") + desc, "" ) #define AND_WHEN( desc ) SECTION( std::string("And when: ") + desc, "" ) #define THEN( desc ) SECTION( std::string(" Then: ") + desc, "" ) #define AND_THEN( desc ) SECTION( std::string(" And: ") + desc, "" ) using Catch::Detail::Approx; // #included from: internal/catch_reenable_warnings.h #define TWOBLUECUBES_CATCH_REENABLE_WARNINGS_H_INCLUDED #ifdef __clang__ # ifdef __ICC // icpc defines the __clang__ macro # pragma warning(pop) # else # pragma clang diagnostic pop # endif #elif defined __GNUC__ # pragma GCC diagnostic pop #endif #endif // TWOBLUECUBES_SINGLE_INCLUDE_CATCH_HPP_INCLUDED catch-1.12.1/test_package/000077500000000000000000000000001325474075300153225ustar00rootroot00000000000000catch-1.12.1/test_package/CMakeLists.txt000066400000000000000000000002661325474075300200660ustar00rootroot00000000000000cmake_minimum_required(VERSION 3.0) project(CatchTest CXX) include(${CMAKE_BINARY_DIR}/conanbuildinfo.cmake) conan_basic_setup() add_executable(${CMAKE_PROJECT_NAME} MainTest.cpp) catch-1.12.1/test_package/MainTest.cpp000066400000000000000000000011621325474075300175520ustar00rootroot00000000000000/* * Created by Phil on 22/10/2010. * Copyright 2010 Two Blue Cubes Ltd * * Distributed under the Boost Software License, Version 1.0. (See accompanying * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) */ #define CATCH_CONFIG_MAIN #include "catch.hpp" unsigned int Factorial( unsigned int number ) { return number > 1 ? Factorial(number-1)*number : 1; } TEST_CASE( "Factorials are computed", "[factorial]" ) { REQUIRE( Factorial(0) == 1 ); REQUIRE( Factorial(1) == 1 ); REQUIRE( Factorial(2) == 2 ); REQUIRE( Factorial(3) == 6 ); REQUIRE( Factorial(10) == 3628800 ); } catch-1.12.1/test_package/conanfile.py000066400000000000000000000010771325474075300176370ustar00rootroot00000000000000#!/usr/bin/env python from os import getenv from os import path from conans import ConanFile from conans import CMake class CatchConanTest(ConanFile): generators = "cmake" settings = "os", "compiler", "arch", "build_type" username = getenv("CONAN_USERNAME", "philsquared") channel = getenv("CONAN_CHANNEL", "testing") requires = "Catch/1.12.1@%s/%s" % (username, channel) def build(self): cmake = CMake(self) cmake.configure(build_dir="./") cmake.build() def test(self): self.run(path.join("bin", "CatchTest"))