normalizing eof for everything
diff --git a/.gitattributes b/.gitattributes
index eff71f0..176a458 100644
--- a/.gitattributes
+++ b/.gitattributes
@@ -1,9 +1 @@
-# Set the default behavior, in case people don't have core.autocrlf set.
* text=auto
-
-# Explicitly declare text files you want to always be normalized and converted
-# to native line endings on checkout.
-*.cpp text
-*.h text
-*.txt text
-*.md text
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 8235504..8cb6936 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,11 +1,11 @@
-# Change Log
-
-## [1.0.0](https://github.com/onqtam/doctest/tree/1.0.0) (2016-05-22)
-**Merged pull requests:**
-
-- Reduce the header size for test users [\#3](https://github.com/onqtam/doctest/pull/3) ([zah](https://github.com/zah))
-- Add a Gitter chat badge to README.md [\#1](https://github.com/onqtam/doctest/pull/1) ([gitter-badger](https://github.com/gitter-badger))
-
-
-
+# Change Log
+
+## [1.0.0](https://github.com/onqtam/doctest/tree/1.0.0) (2016-05-22)
+**Merged pull requests:**
+
+- Reduce the header size for test users [\#3](https://github.com/onqtam/doctest/pull/3) ([zah](https://github.com/zah))
+- Add a Gitter chat badge to README.md [\#1](https://github.com/onqtam/doctest/pull/1) ([gitter-badger](https://github.com/gitter-badger))
+
+
+
\* *This Change Log was automatically generated by [github_changelog_generator](https://github.com/skywinder/Github-Changelog-Generator)*
\ No newline at end of file
diff --git a/CMakeLists.txt b/CMakeLists.txt
index a26ef84..794e57a 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -1,30 +1,30 @@
-cmake_minimum_required(VERSION 2.8)
-
-project(all)
-
-include(scripts/common.cmake)
-
-# when on Travis CI force 64 bit for gcc 4.4 under OSX because -m32 fails
-# saying that it cannot find 'std::exception' as a symbol (or others) for i386
-if(DEFINED ENV{TRAVIS} AND APPLE AND CMAKE_CXX_COMPILER_ID MATCHES "GNU" AND CMAKE_CXX_COMPILER_VERSION VERSION_LESS 4.5)
- add_compiler_flags(-m64)
-endif()
-
-# setup coverage stuff only when COVERALLS_SERVICE_NAME is set (usually on travis CI)
-if(DEFINED ENV{COVERALLS_SERVICE_NAME})
- set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${CMAKE_SOURCE_DIR}/scripts/coveralls-cmake/cmake)
- include(Coveralls)
- coveralls_turn_on_coverage()
-
- coveralls_setup("${CMAKE_SOURCE_DIR}/doctest/doctest.h" ON "${CMAKE_SOURCE_DIR}/scripts/coveralls-cmake/cmake")
-endif()
-
-include_directories("doctest/") # needed here so the coverage tools work - otherwise the "../../doctest" relative path fucks up
-
-file(GLOB subdir_list "${CMAKE_SOURCE_DIR}/examples/*")
-foreach(dir ${subdir_list})
- if(IS_DIRECTORY ${dir})
- get_filename_component(DIRNAME ${dir} NAME)
- add_subdirectory(examples/${DIRNAME})
- endif()
-endforeach()
+cmake_minimum_required(VERSION 2.8)
+
+project(all)
+
+include(scripts/common.cmake)
+
+# when on Travis CI force 64 bit for gcc 4.4 under OSX because -m32 fails
+# saying that it cannot find 'std::exception' as a symbol (or others) for i386
+if(DEFINED ENV{TRAVIS} AND APPLE AND CMAKE_CXX_COMPILER_ID MATCHES "GNU" AND CMAKE_CXX_COMPILER_VERSION VERSION_LESS 4.5)
+ add_compiler_flags(-m64)
+endif()
+
+# setup coverage stuff only when COVERALLS_SERVICE_NAME is set (usually on travis CI)
+if(DEFINED ENV{COVERALLS_SERVICE_NAME})
+ set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${CMAKE_SOURCE_DIR}/scripts/coveralls-cmake/cmake)
+ include(Coveralls)
+ coveralls_turn_on_coverage()
+
+ coveralls_setup("${CMAKE_SOURCE_DIR}/doctest/doctest.h" ON "${CMAKE_SOURCE_DIR}/scripts/coveralls-cmake/cmake")
+endif()
+
+include_directories("doctest/") # needed here so the coverage tools work - otherwise the "../../doctest" relative path fucks up
+
+file(GLOB subdir_list "${CMAKE_SOURCE_DIR}/examples/*")
+foreach(dir ${subdir_list})
+ if(IS_DIRECTORY ${dir})
+ get_filename_component(DIRNAME ${dir} NAME)
+ add_subdirectory(examples/${DIRNAME})
+ endif()
+endforeach()
diff --git a/README.md b/README.md
index 6ec450c..1a9ff1c 100644
--- a/README.md
+++ b/README.md
@@ -1,98 +1,98 @@
-The lightest feature rich C++ single header testing framework
--------
-
-The **doctest** library is inspired by the [**```unittest {}```**](https://wiki.dlang.org/Unittest) functionality of the **D** programming language and **Python**'s [**docstrings**](https://en.wikipedia.org/wiki/Docstring) - tests can be considered a form of documentation and should be able to reside near the production code which they test.
-
-A complete example with a self-registering test that compiles to an executable looks like this:
-
-```c++
-#define DOCTEST_CONFIG_IMPLEMENT_WITH_MAIN
-#include "doctest.h"
-
-int factorial(int number) { return number <= 1 ? number : factorial(number - 1) * number; }
-
-TEST_CASE("testing the factorial function") {
- CHECK(factorial(1) == 1);
- CHECK(factorial(2) == 2);
- CHECK(factorial(10) == 3628800);
-}
-```
-
-Note how a standard C++ operator for the comparison is used - **doctest** has only one core [**assertion macro**](doc/markdown/assertions.md) (instead of many for *less than*, *equals*, *greater than*...) - yet the full expression is decomposed and the left and right values are logged.
-
-It is modeled after [**Catch**](https://github.com/philsquared/Catch) which is currently the most popular and easy to use alternative for testing in C++
-
----------
-
-There are many C++ testing frameworks - [Catch](https://github.com/philsquared/Catch), [Boost.Test](http://www.boost.org/doc/libs/1_60_0/libs/test/doc/html/index.html), [UnitTest++](https://github.com/unittest-cpp/unittest-cpp), [lest](https://github.com/martinmoene/lest), [bandit](http://banditcpp.org/), [igloo](http://igloo-testing.org/), [xUnit++](https://bitbucket.org/moswald/xunit/wiki/Home), [CppTest](http://cpptest.sourceforge.net/), [CppUnit](https://sourceforge.net/projects/cppunit/), [CxxTest](https://github.com/CxxTest/cxxtest), [cpputest](https://github.com/cpputest/cpputest), [googletest](https://github.com/google/googletest), [cute](https://github.com/Kosta-Github/cute) and many [other](https://en.wikipedia.org/wiki/List_of_unit_testing_frameworks#C.2B.2B).
-
-What makes **doctest** different is that it is ultra light on compile times (by [**orders of magnitude**](doc/markdown/benchmarks.md)) and is unintrusive.
-
-The **key** differences between it and other testing libraries are:
-- Ultra light - [**below 10ms**](doc/markdown/benchmarks.md) of compile time overhead for including the header in a source file
-- Offers a way to remove **everything** testing-related from the binary with the [**```DOCTEST_CONFIG_DISABLE```**](doc/markdown/configuration.md) identifier
-- Doesn't pollute the global namespace (everything is in the ```doctest``` namespace) and doesn't drag **any** headers with it
-- Doesn't produce any warnings even on the [**most aggressive**](scripts/common.cmake#L59) warning levels for **MSVC**/**GCC**/**Clang**
-- Very [**portable and well tested**](doc/markdown/features.md#extremely-portable) C++98 - per commit tested on CI with over 200 different builds (valgrind, sanitizers...)
-- Just one header and no external dependencies apart from the C/C++ standard library! (well... same as [**Catch**](https://github.com/philsquared/Catch)...)
-
-This allows the library to be used in more ways than any other - tests can be written directly in the production code!
-
-- This makes the barrier for writing tests **much lower** - you don't have to: **1.** make a separate source file **2.** include a bunch of stuff in it **3.** add it to the build system and **4.** add it to source control - You can just write the tests for a class or a piece of functionality at the bottom of it's source file - or even header file!
-- Tests in the production code can be thought of as documentation or up to date comments - showing how an API is used
-- Tests can be shipped to the customer with the software to diagnose a bug faster
-- [**TDD**](https://en.wikipedia.org/wiki/Test-driven_development) in C++ has never been easier!
-
-The library can be used like any other if you don't like the idea of mixing production code and tests - check out the [**features**](doc/markdown/features.md)
-
-[![Language](https://img.shields.io/badge/language-C++-blue.svg)](https://isocpp.org/)
-[![Standard](https://img.shields.io/badge/c%2B%2B-98-blue.svg)](https://en.wikipedia.org/wiki/C%2B%2B#Standardization)
-[![License](https://img.shields.io/badge/license-MIT-blue.svg)](https://opensource.org/licenses/MIT)
-[![Version](https://badge.fury.io/gh/onqtam%2Fdoctest.svg)](https://github.com/onqtam/doctest/releases)
-[![download](https://img.shields.io/badge/latest%20version%20%20-download-blue.svg)](https://raw.githubusercontent.com/onqtam/doctest/master/doctest/doctest.h)
-[![Join the chat at https://gitter.im/onqtam/doctest](https://badges.gitter.im/onqtam/doctest.svg)](https://gitter.im/onqtam/doctest?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
-[![Try it online](https://img.shields.io/badge/try%20it-online-orange.svg)](http://melpon.org/wandbox/permlink/y0K9IDwJbVWmAIgr)
-
-| master branch | [![Linux/OSX Status](https://travis-ci.org/onqtam/doctest.svg?branch=master)](https://travis-ci.org/onqtam/doctest) | [![Windows status](https://ci.appveyor.com/api/projects/status/j89qxtahyw1dp4gd/branch/master?svg=true)](https://ci.appveyor.com/project/onqtam/doctest/branch/master) | [![Static Analysis](https://scan.coverity.com/projects/7865/badge.svg)](https://scan.coverity.com/projects/onqtam-doctest) |
-|----------------|---------------------------------------------------------------------------------------------------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------|----------------------------------------------------------------------------------------------------------------------------|
-| **dev branch** | [![Linux/OSX Status](https://travis-ci.org/onqtam/doctest.svg?branch=dev)](https://travis-ci.org/onqtam/doctest) | [![Windows status](https://ci.appveyor.com/api/projects/status/j89qxtahyw1dp4gd/branch/dev?svg=true)](https://ci.appveyor.com/project/onqtam/doctest/branch/dev) | |
-
-Documentation
--------------
-
-- [Features and design goals](doc/markdown/features.md) - the complete list of features
-- [Roadmap](doc/markdown/roadmap.md#roadmap) - upcoming features
-- [Tutorial](doc/markdown/tutorial.md#tutorial) - make sure you have read it before the other parts of the documentation
-- [Benchmarks](doc/markdown/benchmarks.md) - compile-time supremacy
-- [Examples](examples)
-
--------------
-
-- [Assertion macros](doc/markdown/assertions.md)
-- [Test cases, subcases and test fixtures](doc/markdown/testcases.md)
-- [Command line](doc/markdown/commandline.md)
-- [Configuration](doc/markdown/configuration.md)
-- [String conversions](doc/markdown/stringification.md)
-- [```main()``` entry point and dealing with shared objects](doc/markdown/main.md)
-- [FAQ](doc/markdown/faq.md)
-
-Contributing
-------------
-
-Support the development of the project with donations! There is a list of planned features which are all important and big - see the [**roadmap**](doc/markdown/roadmap.md). I work on this project in my spare time and every cent is a big deal. I took a break from working in the industry to make open source software.
-
-[![Donate to support](https://pledgie.com/campaigns/31280.png)](https://pledgie.com/campaigns/31280)
-
-Contributions in the form of issues and pull requests are welcome as well.
-
-Open an issue for a discussion before making a pull request to make sure the contribution goes smoothly.
-
-This framework has some design goals which must be kept. Make sure you have read the [**features and design goals**](doc/markdown/features.md) page.
-
-The ```master``` branch is the stable one with the latest release and the ```dev``` branch is on the bleeding edge.
-
-All the framework tests (using ctest) have their output collected when the CMake ```TEST_MODE``` variable is set to ```COLLECT``` (making the new reference output) and later the tests are ran on the CI services (```travis``` and ```appveyor```) - their output is compared with the current reference output in the repository with the ```COMPARE``` mode (default mode is ```COMPARE```).
-
-Code should be formatted with a recent-enough ```clang-format``` using the config file in the root of the repo (or I will do it...)
-
-Testing with compilers different from GCC/Clang/MSVC (and more platforms) is something the project would benefit from.
+The lightest feature rich C++ single header testing framework
+-------
+
+The **doctest** library is inspired by the [**```unittest {}```**](https://wiki.dlang.org/Unittest) functionality of the **D** programming language and **Python**'s [**docstrings**](https://en.wikipedia.org/wiki/Docstring) - tests can be considered a form of documentation and should be able to reside near the production code which they test.
+
+A complete example with a self-registering test that compiles to an executable looks like this:
+
+```c++
+#define DOCTEST_CONFIG_IMPLEMENT_WITH_MAIN
+#include "doctest.h"
+
+int factorial(int number) { return number <= 1 ? number : factorial(number - 1) * number; }
+
+TEST_CASE("testing the factorial function") {
+ CHECK(factorial(1) == 1);
+ CHECK(factorial(2) == 2);
+ CHECK(factorial(10) == 3628800);
+}
+```
+
+Note how a standard C++ operator for the comparison is used - **doctest** has only one core [**assertion macro**](doc/markdown/assertions.md) (instead of many for *less than*, *equals*, *greater than*...) - yet the full expression is decomposed and the left and right values are logged.
+
+It is modeled after [**Catch**](https://github.com/philsquared/Catch) which is currently the most popular and easy to use alternative for testing in C++
+
+---------
+
+There are many C++ testing frameworks - [Catch](https://github.com/philsquared/Catch), [Boost.Test](http://www.boost.org/doc/libs/1_60_0/libs/test/doc/html/index.html), [UnitTest++](https://github.com/unittest-cpp/unittest-cpp), [lest](https://github.com/martinmoene/lest), [bandit](http://banditcpp.org/), [igloo](http://igloo-testing.org/), [xUnit++](https://bitbucket.org/moswald/xunit/wiki/Home), [CppTest](http://cpptest.sourceforge.net/), [CppUnit](https://sourceforge.net/projects/cppunit/), [CxxTest](https://github.com/CxxTest/cxxtest), [cpputest](https://github.com/cpputest/cpputest), [googletest](https://github.com/google/googletest), [cute](https://github.com/Kosta-Github/cute) and many [other](https://en.wikipedia.org/wiki/List_of_unit_testing_frameworks#C.2B.2B).
+
+What makes **doctest** different is that it is ultra light on compile times (by [**orders of magnitude**](doc/markdown/benchmarks.md)) and is unintrusive.
+
+The **key** differences between it and other testing libraries are:
+- Ultra light - [**below 10ms**](doc/markdown/benchmarks.md) of compile time overhead for including the header in a source file
+- Offers a way to remove **everything** testing-related from the binary with the [**```DOCTEST_CONFIG_DISABLE```**](doc/markdown/configuration.md) identifier
+- Doesn't pollute the global namespace (everything is in the ```doctest``` namespace) and doesn't drag **any** headers with it
+- Doesn't produce any warnings even on the [**most aggressive**](scripts/common.cmake#L59) warning levels for **MSVC**/**GCC**/**Clang**
+- Very [**portable and well tested**](doc/markdown/features.md#extremely-portable) C++98 - per commit tested on CI with over 200 different builds (valgrind, sanitizers...)
+- Just one header and no external dependencies apart from the C/C++ standard library! (well... same as [**Catch**](https://github.com/philsquared/Catch)...)
+
+This allows the library to be used in more ways than any other - tests can be written directly in the production code!
+
+- This makes the barrier for writing tests **much lower** - you don't have to: **1.** make a separate source file **2.** include a bunch of stuff in it **3.** add it to the build system and **4.** add it to source control - You can just write the tests for a class or a piece of functionality at the bottom of it's source file - or even header file!
+- Tests in the production code can be thought of as documentation or up to date comments - showing how an API is used
+- Tests can be shipped to the customer with the software to diagnose a bug faster
+- [**TDD**](https://en.wikipedia.org/wiki/Test-driven_development) in C++ has never been easier!
+
+The library can be used like any other if you don't like the idea of mixing production code and tests - check out the [**features**](doc/markdown/features.md)
+
+[![Language](https://img.shields.io/badge/language-C++-blue.svg)](https://isocpp.org/)
+[![Standard](https://img.shields.io/badge/c%2B%2B-98-blue.svg)](https://en.wikipedia.org/wiki/C%2B%2B#Standardization)
+[![License](https://img.shields.io/badge/license-MIT-blue.svg)](https://opensource.org/licenses/MIT)
+[![Version](https://badge.fury.io/gh/onqtam%2Fdoctest.svg)](https://github.com/onqtam/doctest/releases)
+[![download](https://img.shields.io/badge/latest%20version%20%20-download-blue.svg)](https://raw.githubusercontent.com/onqtam/doctest/master/doctest/doctest.h)
+[![Join the chat at https://gitter.im/onqtam/doctest](https://badges.gitter.im/onqtam/doctest.svg)](https://gitter.im/onqtam/doctest?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
+[![Try it online](https://img.shields.io/badge/try%20it-online-orange.svg)](http://melpon.org/wandbox/permlink/y0K9IDwJbVWmAIgr)
+
+| master branch | [![Linux/OSX Status](https://travis-ci.org/onqtam/doctest.svg?branch=master)](https://travis-ci.org/onqtam/doctest) | [![Windows status](https://ci.appveyor.com/api/projects/status/j89qxtahyw1dp4gd/branch/master?svg=true)](https://ci.appveyor.com/project/onqtam/doctest/branch/master) | [![Static Analysis](https://scan.coverity.com/projects/7865/badge.svg)](https://scan.coverity.com/projects/onqtam-doctest) |
+|----------------|---------------------------------------------------------------------------------------------------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------|----------------------------------------------------------------------------------------------------------------------------|
+| **dev branch** | [![Linux/OSX Status](https://travis-ci.org/onqtam/doctest.svg?branch=dev)](https://travis-ci.org/onqtam/doctest) | [![Windows status](https://ci.appveyor.com/api/projects/status/j89qxtahyw1dp4gd/branch/dev?svg=true)](https://ci.appveyor.com/project/onqtam/doctest/branch/dev) | |
+
+Documentation
+-------------
+
+- [Features and design goals](doc/markdown/features.md) - the complete list of features
+- [Roadmap](doc/markdown/roadmap.md#roadmap) - upcoming features
+- [Tutorial](doc/markdown/tutorial.md#tutorial) - make sure you have read it before the other parts of the documentation
+- [Benchmarks](doc/markdown/benchmarks.md) - compile-time supremacy
+- [Examples](examples)
+
+-------------
+
+- [Assertion macros](doc/markdown/assertions.md)
+- [Test cases, subcases and test fixtures](doc/markdown/testcases.md)
+- [Command line](doc/markdown/commandline.md)
+- [Configuration](doc/markdown/configuration.md)
+- [String conversions](doc/markdown/stringification.md)
+- [```main()``` entry point and dealing with shared objects](doc/markdown/main.md)
+- [FAQ](doc/markdown/faq.md)
+
+Contributing
+------------
+
+Support the development of the project with donations! There is a list of planned features which are all important and big - see the [**roadmap**](doc/markdown/roadmap.md). I work on this project in my spare time and every cent is a big deal. I took a break from working in the industry to make open source software.
+
+[![Donate to support](https://pledgie.com/campaigns/31280.png)](https://pledgie.com/campaigns/31280)
+
+Contributions in the form of issues and pull requests are welcome as well.
+
+Open an issue for a discussion before making a pull request to make sure the contribution goes smoothly.
+
+This framework has some design goals which must be kept. Make sure you have read the [**features and design goals**](doc/markdown/features.md) page.
+
+The ```master``` branch is the stable one with the latest release and the ```dev``` branch is on the bleeding edge.
+
+All the framework tests (using ctest) have their output collected when the CMake ```TEST_MODE``` variable is set to ```COLLECT``` (making the new reference output) and later the tests are ran on the CI services (```travis``` and ```appveyor```) - their output is compared with the current reference output in the repository with the ```COMPARE``` mode (default mode is ```COMPARE```).
+
+Code should be formatted with a recent-enough ```clang-format``` using the config file in the root of the repo (or I will do it...)
+
+Testing with compilers different from GCC/Clang/MSVC (and more platforms) is something the project would benefit from.
diff --git a/appveyor.yml b/appveyor.yml
index 6f51d3c..080c506 100644
--- a/appveyor.yml
+++ b/appveyor.yml
@@ -1,116 +1,116 @@
-# http://www.appveyor.com/docs/appveyor-yml
-
-notifications:
- - provider: Email
- to:
- - vik.kirilov@gmail.com
- on_build_status_changed: true
- on_build_failure: true
- on_build_success: false
- # gitter
- - provider: Webhook
- url: https://webhooks.gitter.im/e/3a78202a235c0325e516
- on_build_status_changed: true
- on_build_failure: true
- on_build_success: false
-
-clone_depth: 5
-branches:
- except:
- - gh-pages
- - coverity_scan
-
-matrix:
- fast_finish: false
-
-environment:
- matrix:
- - platform: x86
- configuration: Debug
- arch: "Win32"
- VS_GEN: "Visual Studio 9 2008"
- - platform: x86
- configuration: Release
- arch: "Win32"
- VS_GEN: "Visual Studio 9 2008"
-## THE FOLLOWING ARE DISABLED BECAUSE CMAKE CANNOT FIND THE COMPILER FOR Win64
-# - platform: x64
-# configuration: Debug
-# arch: "x64"
-# VS_GEN: "Visual Studio 9 2008 Win64"
-# - platform: x64
-# configuration: Release
-# arch: "x64"
-# VS_GEN: "Visual Studio 9 2008 Win64"
- - platform: x86
- configuration: Debug
- arch: "Win32"
- VS_GEN: "Visual Studio 10 2010"
- - platform: x86
- configuration: Release
- arch: "Win32"
- VS_GEN: "Visual Studio 10 2010"
- - platform: x64
- configuration: Debug
- arch: "x64"
- VS_GEN: "Visual Studio 10 2010 Win64"
- - platform: x64
- configuration: Release
- arch: "x64"
- VS_GEN: "Visual Studio 10 2010 Win64"
- - platform: x86
- configuration: Debug
- arch: "Win32"
- VS_GEN: "Visual Studio 11 2012"
- - platform: x86
- configuration: Release
- arch: "Win32"
- VS_GEN: "Visual Studio 11 2012"
- - platform: x64
- configuration: Debug
- arch: "x64"
- VS_GEN: "Visual Studio 11 2012 Win64"
- - platform: x64
- configuration: Release
- arch: "x64"
- VS_GEN: "Visual Studio 11 2012 Win64"
- - platform: x86
- configuration: Debug
- arch: "Win32"
- VS_GEN: "Visual Studio 12 2013"
- - platform: x86
- configuration: Release
- arch: "Win32"
- VS_GEN: "Visual Studio 12 2013"
- - platform: x64
- configuration: Debug
- arch: "x64"
- VS_GEN: "Visual Studio 12 2013 Win64"
- - platform: x64
- configuration: Release
- arch: "x64"
- VS_GEN: "Visual Studio 12 2013 Win64"
- - platform: x86
- configuration: Debug
- arch: "Win32"
- VS_GEN: "Visual Studio 14 2015"
- - platform: x86
- configuration: Release
- arch: "Win32"
- VS_GEN: "Visual Studio 14 2015"
- - platform: x64
- configuration: Debug
- arch: "x64"
- VS_GEN: "Visual Studio 14 2015 Win64"
- - platform: x64
- configuration: Release
- arch: "x64"
- VS_GEN: "Visual Studio 14 2015 Win64"
-
-before_build:
- - cmake . -G "%VS_GEN%"
-build_script:
- - msbuild all.sln /p:Configuration=%Configuration%;Platform=%arch% /maxcpucount
-test_script:
- - cmake . -DTEST_MODE=COMPARE
- - ctest -C %configuration% --output-on-failure
+# http://www.appveyor.com/docs/appveyor-yml
+
+notifications:
+ - provider: Email
+ to:
+ - vik.kirilov@gmail.com
+ on_build_status_changed: true
+ on_build_failure: true
+ on_build_success: false
+ # gitter
+ - provider: Webhook
+ url: https://webhooks.gitter.im/e/3a78202a235c0325e516
+ on_build_status_changed: true
+ on_build_failure: true
+ on_build_success: false
+
+clone_depth: 5
+branches:
+ except:
+ - gh-pages
+ - coverity_scan
+
+matrix:
+ fast_finish: false
+
+environment:
+ matrix:
+ - platform: x86
+ configuration: Debug
+ arch: "Win32"
+ VS_GEN: "Visual Studio 9 2008"
+ - platform: x86
+ configuration: Release
+ arch: "Win32"
+ VS_GEN: "Visual Studio 9 2008"
+## THE FOLLOWING ARE DISABLED BECAUSE CMAKE CANNOT FIND THE COMPILER FOR Win64
+# - platform: x64
+# configuration: Debug
+# arch: "x64"
+# VS_GEN: "Visual Studio 9 2008 Win64"
+# - platform: x64
+# configuration: Release
+# arch: "x64"
+# VS_GEN: "Visual Studio 9 2008 Win64"
+ - platform: x86
+ configuration: Debug
+ arch: "Win32"
+ VS_GEN: "Visual Studio 10 2010"
+ - platform: x86
+ configuration: Release
+ arch: "Win32"
+ VS_GEN: "Visual Studio 10 2010"
+ - platform: x64
+ configuration: Debug
+ arch: "x64"
+ VS_GEN: "Visual Studio 10 2010 Win64"
+ - platform: x64
+ configuration: Release
+ arch: "x64"
+ VS_GEN: "Visual Studio 10 2010 Win64"
+ - platform: x86
+ configuration: Debug
+ arch: "Win32"
+ VS_GEN: "Visual Studio 11 2012"
+ - platform: x86
+ configuration: Release
+ arch: "Win32"
+ VS_GEN: "Visual Studio 11 2012"
+ - platform: x64
+ configuration: Debug
+ arch: "x64"
+ VS_GEN: "Visual Studio 11 2012 Win64"
+ - platform: x64
+ configuration: Release
+ arch: "x64"
+ VS_GEN: "Visual Studio 11 2012 Win64"
+ - platform: x86
+ configuration: Debug
+ arch: "Win32"
+ VS_GEN: "Visual Studio 12 2013"
+ - platform: x86
+ configuration: Release
+ arch: "Win32"
+ VS_GEN: "Visual Studio 12 2013"
+ - platform: x64
+ configuration: Debug
+ arch: "x64"
+ VS_GEN: "Visual Studio 12 2013 Win64"
+ - platform: x64
+ configuration: Release
+ arch: "x64"
+ VS_GEN: "Visual Studio 12 2013 Win64"
+ - platform: x86
+ configuration: Debug
+ arch: "Win32"
+ VS_GEN: "Visual Studio 14 2015"
+ - platform: x86
+ configuration: Release
+ arch: "Win32"
+ VS_GEN: "Visual Studio 14 2015"
+ - platform: x64
+ configuration: Debug
+ arch: "x64"
+ VS_GEN: "Visual Studio 14 2015 Win64"
+ - platform: x64
+ configuration: Release
+ arch: "x64"
+ VS_GEN: "Visual Studio 14 2015 Win64"
+
+before_build:
+ - cmake . -G "%VS_GEN%"
+build_script:
+ - msbuild all.sln /p:Configuration=%Configuration%;Platform=%arch% /maxcpucount
+test_script:
+ - cmake . -DTEST_MODE=COMPARE
+ - ctest -C %configuration% --output-on-failure
diff --git a/doc/markdown/assertions.md b/doc/markdown/assertions.md
index 5d8b233..9377dde 100644
--- a/doc/markdown/assertions.md
+++ b/doc/markdown/assertions.md
@@ -1,89 +1,89 @@
-## Assertion macros
-
-Most test frameworks have a large collection of assertion macros to capture all possible conditional forms (```_EQUALS```, ```_NOTEQUALS```, ```_GREATER_THAN``` etc).
-
-**doctest** is different (but it's like [**Catch**](https://github.com/philsquared/Catch) in this regard). Because it decomposes natural C-style conditional expressions most of these forms are reduced to one or two that you will use all the time. That said there are a rich set of auxiliary macros as well. We'll describe all of these here.
-
-Most of these macros come in two forms:
-
-## Natural Expressions
-
-The ```REQUIRE``` family of macros tests an expression and aborts the test case if it fails.
-
-The ```CHECK``` family are equivalent but execution continues in the same test case even if the assertion fails. This is useful if you have a series of essentially orthogonal assertions and it is useful to see all the results rather than stopping at the first failure.
-
-The ```WARN``` family will just print the error when the condition is not met - but will not fail the test case.
-
-* **REQUIRE(** _expression_ **)**
-* **CHECK(** _expression_ **)**
-* **WARN(** _expression_ **)**
-
-Evaluates the expression and records the result. If an exception is thrown it is caught, reported, and counted as a failure (unless it is a **WARN**). These are the macros you will use most of the time
-
-Examples:
-
-```c++
-CHECK(str == "string value");
-CHECK(thisReturnsTrue());
-REQUIRE(i == 42);
-```
-
-* **REQUIRE_FALSE(** _expression_ **)**
-* **CHECK_FALSE(** _expression_ **)**
-* **WARN_FALSE(** _expression_ **)**
-
-Evaluates the expression and records the _logical NOT_ of the result. If an exception is thrown it is caught, reported, and counted as a failure.
-(these forms exist as a workaround for the fact that ! prefixed expressions cannot be decomposed).
-
-Example:
-
-```c++
-REQUIRE_FALSE(thisReturnsFalse());
-```
-
-### Floating point comparisons
-
-When comparing floating point numbers - especially if at least one of them has been computed - great care must be taken to allow for rounding errors and inexact representations.
-
-**doctest** provides a way to perform tolerant comparisons of floating point values through use of a wrapper class called ```doctest::Approx```. ```doctest::Approx``` can be used on either side of a comparison expression. It overloads the comparisons operators to take a tolerance into account. Here's a simple example:
-
-```c++
-REQUIRE(performComputation() == doctest::Approx(2.1));
-```
-
-By default a small epsilon value is used that covers many simple cases of rounding errors. When this is insufficient the epsilon value (the amount within which a difference either way is ignored) can be specified by calling the ```epsilon()``` method on the ```doctest::Approx``` instance. e.g.:
-
-```c++
-REQUIRE(22/7 == doctest::Approx(3.141).epsilon(0.01));
-```
-
-When dealing with very large or very small numbers it can be useful to specify a scale, which can be achieved by calling the ```scale()``` method on the ```doctest::Approx``` instance.
-
-## Exceptions
-
-* **REQUIRE_THROWS(** _expression_ **)**
-* **CHECK_THROWS(** _expression_ **)**
-* **WARN_THROWS(** _expression_ **)**
-
-Expects that an exception (of any type) is be thrown during evaluation of the expression.
-
-* **REQUIRE_THROWS_AS(** _expression_, _exception type_ **)**
-* **CHECK_THROWS_AS(** _expression_, _exception type_ **)**
-* **WARN_THROWS_AS(** _expression_, _exception type_ **)**
-
-Expects that an exception of the _specified type_ is thrown during evaluation of the expression.
-
-* **REQUIRE_NOTHROW(** _expression_ **)**
-* **CHECK_NOTHROW(** _expression_ **)**
-* **WARN_NOTHROW(** _expression_ **)**
-
-Expects that no exception is thrown during evaluation of the expression.
-
---------
-
-- Check out the [**example**](../../examples/assertion_macros/main.cpp) which shows many of these macros
-- Do not wrap assertion macros in ```try```/```catch``` - the REQUIRE macros throw exceptions to end the test case execution!
-
----------------
-
-[Home](readme.md#reference)
+## Assertion macros
+
+Most test frameworks have a large collection of assertion macros to capture all possible conditional forms (```_EQUALS```, ```_NOTEQUALS```, ```_GREATER_THAN``` etc).
+
+**doctest** is different (but it's like [**Catch**](https://github.com/philsquared/Catch) in this regard). Because it decomposes natural C-style conditional expressions most of these forms are reduced to one or two that you will use all the time. That said there are a rich set of auxiliary macros as well. We'll describe all of these here.
+
+Most of these macros come in two forms:
+
+## Natural Expressions
+
+The ```REQUIRE``` family of macros tests an expression and aborts the test case if it fails.
+
+The ```CHECK``` family are equivalent but execution continues in the same test case even if the assertion fails. This is useful if you have a series of essentially orthogonal assertions and it is useful to see all the results rather than stopping at the first failure.
+
+The ```WARN``` family will just print the error when the condition is not met - but will not fail the test case.
+
+* **REQUIRE(** _expression_ **)**
+* **CHECK(** _expression_ **)**
+* **WARN(** _expression_ **)**
+
+Evaluates the expression and records the result. If an exception is thrown it is caught, reported, and counted as a failure (unless it is a **WARN**). These are the macros you will use most of the time
+
+Examples:
+
+```c++
+CHECK(str == "string value");
+CHECK(thisReturnsTrue());
+REQUIRE(i == 42);
+```
+
+* **REQUIRE_FALSE(** _expression_ **)**
+* **CHECK_FALSE(** _expression_ **)**
+* **WARN_FALSE(** _expression_ **)**
+
+Evaluates the expression and records the _logical NOT_ of the result. If an exception is thrown it is caught, reported, and counted as a failure.
+(these forms exist as a workaround for the fact that ! prefixed expressions cannot be decomposed).
+
+Example:
+
+```c++
+REQUIRE_FALSE(thisReturnsFalse());
+```
+
+### Floating point comparisons
+
+When comparing floating point numbers - especially if at least one of them has been computed - great care must be taken to allow for rounding errors and inexact representations.
+
+**doctest** provides a way to perform tolerant comparisons of floating point values through use of a wrapper class called ```doctest::Approx```. ```doctest::Approx``` can be used on either side of a comparison expression. It overloads the comparisons operators to take a tolerance into account. Here's a simple example:
+
+```c++
+REQUIRE(performComputation() == doctest::Approx(2.1));
+```
+
+By default a small epsilon value is used that covers many simple cases of rounding errors. When this is insufficient the epsilon value (the amount within which a difference either way is ignored) can be specified by calling the ```epsilon()``` method on the ```doctest::Approx``` instance. e.g.:
+
+```c++
+REQUIRE(22/7 == doctest::Approx(3.141).epsilon(0.01));
+```
+
+When dealing with very large or very small numbers it can be useful to specify a scale, which can be achieved by calling the ```scale()``` method on the ```doctest::Approx``` instance.
+
+## Exceptions
+
+* **REQUIRE_THROWS(** _expression_ **)**
+* **CHECK_THROWS(** _expression_ **)**
+* **WARN_THROWS(** _expression_ **)**
+
+Expects that an exception (of any type) is be thrown during evaluation of the expression.
+
+* **REQUIRE_THROWS_AS(** _expression_, _exception type_ **)**
+* **CHECK_THROWS_AS(** _expression_, _exception type_ **)**
+* **WARN_THROWS_AS(** _expression_, _exception type_ **)**
+
+Expects that an exception of the _specified type_ is thrown during evaluation of the expression.
+
+* **REQUIRE_NOTHROW(** _expression_ **)**
+* **CHECK_NOTHROW(** _expression_ **)**
+* **WARN_NOTHROW(** _expression_ **)**
+
+Expects that no exception is thrown during evaluation of the expression.
+
+--------
+
+- Check out the [**example**](../../examples/assertion_macros/main.cpp) which shows many of these macros
+- Do not wrap assertion macros in ```try```/```catch``` - the REQUIRE macros throw exceptions to end the test case execution!
+
+---------------
+
+[Home](readme.md#reference)
diff --git a/doc/markdown/benchmarks.md b/doc/markdown/benchmarks.md
index 4f079ff..8f1c968 100644
--- a/doc/markdown/benchmarks.md
+++ b/doc/markdown/benchmarks.md
@@ -9,14 +9,14 @@
The script generates 501 source files and in 500 of them makes a function in the form of ```int f135() { return 135; }``` and in ```main.cpp``` it forward declares all the 500 such dummy functions and accumulates their result to return from the ```main()``` function. This is done to ensure that all source files are built and that the linker doesn't remove/optimize anything.
- **baseline** - how much time the source files need for a single threaded build with ```msbuild```/```mingw32-make```
-- **+ implementation** - only in ```main.cpp``` the header is included with a ```#define``` before it so the test runner gets instantiated:
+- **+ implementation** - only in ```main.cpp``` the header is included with a ```#define``` before it so the test runner gets instantiated:
```c++
#define DOCTEST_CONFIG_IMPLEMENT_WITH_MAIN
#include "doctest.h"
```
- **+ header everywhere** - the framework header is also included in all the other source files
-- **+ a test everywhere** - in all the source files there is 1 test case with 1 assertions defined
+- **+ a test everywhere** - in all the source files there is 1 test case with 1 assertions defined
- **+ disabled** - **doctest** specific - only this framework can remove everything related to it from the binary
## doctest
@@ -45,13 +45,13 @@
- instantiating the test runner in one source file costs ~1 second ```implementation - baseline```
- the inclusion of ```doctest.h``` in one source file costs below 9ms ```(header_everywhere - implementation) / 500```
-- the addition of a test costs below 10ms ```(a_test_everywhere - header_everywhere) / 500```
+- the addition of a test costs below 10ms ```(a_test_everywhere - header_everywhere) / 500```
(below 18ms for MinGW-w64 but Linux GCC will be much faster)
- using the library everywhere with tests - but everything disabled - costs less than 2 seconds ```disabled - baseline```
### [Catch](https://github.com/philsquared/Catch)
-- instantiating the test runner in one source file costs ~4 second ```implementation - baseline```
+- instantiating the test runner in one source file costs ~4 second ```implementation - baseline```
(~12 seconds for MinGW-w64 but Linux GCC will be much faster)
- the inclusion of ```catch.hpp``` in one source file costs around 430ms ```(header_everywhere - implementation) / 500```
(below 280ms for MinGW-w64 which is really odd)
diff --git a/doc/markdown/commandline.md b/doc/markdown/commandline.md
index 03ff23e..10059eb 100644
--- a/doc/markdown/commandline.md
+++ b/doc/markdown/commandline.md
@@ -1,56 +1,56 @@
-## Command line
-
-**doctest** works quite nicely without any command line options at all - but for more control there are a bunch that are available.
-
-**Query flags** - after the result is printed the program quits without executing any test cases (and if the framework is integrated into a client codebase which [**supplies it's own ```main()``` entry point**](main.md) - the program should check the result of ```doctest::Context::shouldExit()``` after calling ```doctest::Context::run()``` and should exit - this is left up to the user).
-
-**Int/String options** - they require a value after the ```=``` sign - without spaces! For example: ```--order-by=rand```.
-
-**Bool options** - they expect ```1```/```yes```/```on```/```true``` or ```0```/```no```/```off```/```false``` after the ```=``` sign - but they can also be used like flags and the ```=value``` part can be skipped - then ```true``` is assumed.
-
-**Filters** use wildcards for matching values - where ```*``` means "match any sequence" and ```?``` means "match any one character".
-To pass a pattern with an interval use ```""``` like this: ```--test-case="*no sound*,vaguely named test number ?"```.
-
-All the options can also be set with code if the user [**supplies the ```main()``` function**](main.md) so an option is always with some value.
-
-| Query Flags | Description |
-|:------------|-------------|
-| ```-?``` ```--help``` ```-h``` | Prints a help message listing all these flags/options |
-| ```-v``` ```--version``` | Prints the version of the **doctest** framework |
-| ```-c``` ```--count``` | Prints the number of test cases matching the current filters (see below) |
-| ```-ltc``` ```--list-test-cases``` | Lists all test cases by name which match the current filters (see below) |
-| ```-lts``` ```--list-test-suites``` | Lists all test suites by name which have at least one test case matching the current filters (see below) |
-| **Int/String Options** | <hr> |
-| ```-tc``` ```--test-case=<filters>``` | Filters test cases based on their name. By default all test cases match but if a value is given to this filter like ```--test-case=*math*,*sound*``` then only test cases who match atleast one of the patterns in the comma-separated list with wildcards will get executed/counted/listed |
-| ```-tce``` ```--test-case-exclude=<filters>``` | Same as the ```-test-case=<filters>``` option but if any of the patterns in the comma-separated list of values matches - then the test case is skipped |
-| ```-sf``` ```--source-file=<filters>``` | Same as ```--test-case=<filters>``` but filters based on the file in which test cases are written |
-| ```-sfe``` ```--source-file-exclude=<filters>``` | Same as ```--test-case-exclude=<filters>``` but filters based on the file in which test cases are written |
-| ```-ts``` ```--test-suite=<filters>``` | Same as ```--test-case=<filters>``` but filters based on the test suite in which test cases are in |
-| ```-tse``` ```--test-suite-exclude=<filters>``` | Same as ```--test-case-exclude=<filters>``` but filters based on the test suite in which test cases are in |
-| ```-ob``` ```--order-by=<string>``` | Test cases will be sorted before being executed either by **the file in which they are** / **the test suite they are in** / **their name** / **random**. The possible values of ```<string>``` are ```file```/```suite```/```name```/```rand```. The default is ```file``` |
-| ```-rs``` ```--rand-seed=<int>``` | The seed for random ordering |
-| ```-f``` ```--first=<int>``` | The **first** test case to execute which passes the current filters - for range-based execution - see [**the example**](../../examples/range_based_execution/) (the **run.py** script) |
-| ```-l``` ```--last=<int>``` | The **last** test case to execute which passes the current filters - for range-based execution - see [**the example**](../../examples/range_based_execution/) (the **run.py** script) |
-| ```-aa``` ```--abort-after=<int>``` | The testing framework will stop executing test cases/assertions after this many failed assertions. The default is 0 which means don't stop at all |
-| **Bool Options** | <hr> |
-| ```-s``` ```--success=<bool>``` | To include successful assertions in the output |
-| ```-cs``` ```--case-sensitive=<bool>``` | Filters being treated as case sensitive |
-| ```-e``` ```--exit=<bool>``` | Exits after the tests finish - this is meaningful only when the client has [**provided the ```main()``` entry point**](main.md) - the program should check ```doctest::Context::shouldExit()``` after calling ```doctest::Context::run()``` and should exit - this is left up to the user. The idea is to be able to execute just the tests in a client program and to not continue with it's execution |
-| ```-no``` ```--no-overrides=<bool>``` | Disables procedural overrides of options which are only possible if the client has [**provided the ```main()``` entry point**](main.md). This is useful if the program has some default options set (which override the command line) but you want to set an option differently from the command line without recompiling.|
-| ```-nt``` ```--no-throw=<bool>``` | Skips [**exceptions-related assertion**](assertions.md#exceptions) checks |
-| ```-ne``` ```--no-exitcode=<bool>``` | Always returns a successful exit code - even if a test case has failed |
-| ```-nr``` ```--no-run=<bool>``` | Skips all runtime **doctest** operations (except the test registering which happens before the program enters ```main()```). This is useful if the testing framework is integrated into a client codebase which has [**provided the ```main()``` entry point**](main.md) and the user wants to skip running the tests and just use the program |
-| ```-nc``` ```--no-colors=<bool>``` | Disables colors in the output |
-| ```-nb``` ```--no-breaks=<bool>``` | Disables breakpoints in debuggers when an assertion fails |
-| ```-npf``` ```--no-path-filenames=<bool>``` | Paths are removed from the output when a filename is printed - useful if you want the same output from the testing framework on different environments |
-| | |
-
-All the flags/options also come with a prefixed version (with ```-dt-``` at the front) - for example ```--version``` can be used also with ```--dt-version``` or ```-dt-v```.
-
-All the unprefixed versions listed here can be disabled with the [**```DOCTEST_CONFIG_NO_UNPREFIXED_OPTIONS```**](configuration.md) define.
-
-This is done for easy interoperability with client command line option handling when the testing framework is integrated within a client codebase - all **doctest** related flags/options can be prefixed so there are no clashes and so that the user can exclude everything starting with ```-dt-``` from their option parsing.
-
----------------
-
-[Home](readme.md#reference)
+## Command line
+
+**doctest** works quite nicely without any command line options at all - but for more control there are a bunch that are available.
+
+**Query flags** - after the result is printed the program quits without executing any test cases (and if the framework is integrated into a client codebase which [**supplies it's own ```main()``` entry point**](main.md) - the program should check the result of ```doctest::Context::shouldExit()``` after calling ```doctest::Context::run()``` and should exit - this is left up to the user).
+
+**Int/String options** - they require a value after the ```=``` sign - without spaces! For example: ```--order-by=rand```.
+
+**Bool options** - they expect ```1```/```yes```/```on```/```true``` or ```0```/```no```/```off```/```false``` after the ```=``` sign - but they can also be used like flags and the ```=value``` part can be skipped - then ```true``` is assumed.
+
+**Filters** use wildcards for matching values - where ```*``` means "match any sequence" and ```?``` means "match any one character".
+To pass a pattern with an interval use ```""``` like this: ```--test-case="*no sound*,vaguely named test number ?"```.
+
+All the options can also be set with code if the user [**supplies the ```main()``` function**](main.md) so an option is always with some value.
+
+| Query Flags | Description |
+|:------------|-------------|
+| ```-?``` ```--help``` ```-h``` | Prints a help message listing all these flags/options |
+| ```-v``` ```--version``` | Prints the version of the **doctest** framework |
+| ```-c``` ```--count``` | Prints the number of test cases matching the current filters (see below) |
+| ```-ltc``` ```--list-test-cases``` | Lists all test cases by name which match the current filters (see below) |
+| ```-lts``` ```--list-test-suites``` | Lists all test suites by name which have at least one test case matching the current filters (see below) |
+| **Int/String Options** | <hr> |
+| ```-tc``` ```--test-case=<filters>``` | Filters test cases based on their name. By default all test cases match but if a value is given to this filter like ```--test-case=*math*,*sound*``` then only test cases who match atleast one of the patterns in the comma-separated list with wildcards will get executed/counted/listed |
+| ```-tce``` ```--test-case-exclude=<filters>``` | Same as the ```-test-case=<filters>``` option but if any of the patterns in the comma-separated list of values matches - then the test case is skipped |
+| ```-sf``` ```--source-file=<filters>``` | Same as ```--test-case=<filters>``` but filters based on the file in which test cases are written |
+| ```-sfe``` ```--source-file-exclude=<filters>``` | Same as ```--test-case-exclude=<filters>``` but filters based on the file in which test cases are written |
+| ```-ts``` ```--test-suite=<filters>``` | Same as ```--test-case=<filters>``` but filters based on the test suite in which test cases are in |
+| ```-tse``` ```--test-suite-exclude=<filters>``` | Same as ```--test-case-exclude=<filters>``` but filters based on the test suite in which test cases are in |
+| ```-ob``` ```--order-by=<string>``` | Test cases will be sorted before being executed either by **the file in which they are** / **the test suite they are in** / **their name** / **random**. The possible values of ```<string>``` are ```file```/```suite```/```name```/```rand```. The default is ```file``` |
+| ```-rs``` ```--rand-seed=<int>``` | The seed for random ordering |
+| ```-f``` ```--first=<int>``` | The **first** test case to execute which passes the current filters - for range-based execution - see [**the example**](../../examples/range_based_execution/) (the **run.py** script) |
+| ```-l``` ```--last=<int>``` | The **last** test case to execute which passes the current filters - for range-based execution - see [**the example**](../../examples/range_based_execution/) (the **run.py** script) |
+| ```-aa``` ```--abort-after=<int>``` | The testing framework will stop executing test cases/assertions after this many failed assertions. The default is 0 which means don't stop at all |
+| **Bool Options** | <hr> |
+| ```-s``` ```--success=<bool>``` | To include successful assertions in the output |
+| ```-cs``` ```--case-sensitive=<bool>``` | Filters being treated as case sensitive |
+| ```-e``` ```--exit=<bool>``` | Exits after the tests finish - this is meaningful only when the client has [**provided the ```main()``` entry point**](main.md) - the program should check ```doctest::Context::shouldExit()``` after calling ```doctest::Context::run()``` and should exit - this is left up to the user. The idea is to be able to execute just the tests in a client program and to not continue with it's execution |
+| ```-no``` ```--no-overrides=<bool>``` | Disables procedural overrides of options which are only possible if the client has [**provided the ```main()``` entry point**](main.md). This is useful if the program has some default options set (which override the command line) but you want to set an option differently from the command line without recompiling.|
+| ```-nt``` ```--no-throw=<bool>``` | Skips [**exceptions-related assertion**](assertions.md#exceptions) checks |
+| ```-ne``` ```--no-exitcode=<bool>``` | Always returns a successful exit code - even if a test case has failed |
+| ```-nr``` ```--no-run=<bool>``` | Skips all runtime **doctest** operations (except the test registering which happens before the program enters ```main()```). This is useful if the testing framework is integrated into a client codebase which has [**provided the ```main()``` entry point**](main.md) and the user wants to skip running the tests and just use the program |
+| ```-nc``` ```--no-colors=<bool>``` | Disables colors in the output |
+| ```-nb``` ```--no-breaks=<bool>``` | Disables breakpoints in debuggers when an assertion fails |
+| ```-npf``` ```--no-path-filenames=<bool>``` | Paths are removed from the output when a filename is printed - useful if you want the same output from the testing framework on different environments |
+| | |
+
+All the flags/options also come with a prefixed version (with ```-dt-``` at the front) - for example ```--version``` can be used also with ```--dt-version``` or ```-dt-v```.
+
+All the unprefixed versions listed here can be disabled with the [**```DOCTEST_CONFIG_NO_UNPREFIXED_OPTIONS```**](configuration.md) define.
+
+This is done for easy interoperability with client command line option handling when the testing framework is integrated within a client codebase - all **doctest** related flags/options can be prefixed so there are no clashes and so that the user can exclude everything starting with ```-dt-``` from their option parsing.
+
+---------------
+
+[Home](readme.md#reference)
diff --git a/doc/markdown/configuration.md b/doc/markdown/configuration.md
index af3a69b..cbbee62 100644
--- a/doc/markdown/configuration.md
+++ b/doc/markdown/configuration.md
@@ -1,36 +1,36 @@
-## Configuration
-
-**doctest** is designed to "just work" as much as possible. It exposes a small set of defines for configuring how it is built.
-
-For most people the only configuration needed is telling **doctest** which source file should host all the implementation code:
-
-- **```DOCTEST_CONFIG_IMPLEMENT_WITH_MAIN```**
-
- ```c++
-#define DOCTEST_CONFIG_IMPLEMENT_WITH_MAIN
-#include "doctest.h"
- ```
-
- This should be done in only one source file! Otherwise there will be linker errors and slower build times.
-
-- **```DOCTEST_CONFIG_IMPLEMENT```** - if the client wants to [**supply the ```main()``` function**](main.md) (either to set an option with some value from the code or to integrate the framework into his existing project codebase) this define should be used.
-
-- **```DOCTEST_CONFIG_DISABLE```** - the next most important configuration option - when defined globally in the whole project before the inclusion of the framework header - everything testing - related is removed from the binary - including most of the framework implementation and every test case written anywhere! This is one of the most unique features of **doctest**.
-
-- **```DOCTEST_CONFIG_NO_SHORT_MACRO_NAMES```** - this will remove all macros from **doctest** that don't have the **```DOCTEST_```** prefix - like **```CHECK```**, **```TEST_CASE```** and **```SUBCASE```**. Then only the full macro names will be available - **```DOCTEST_CHECK```**, **```DOCTEST_TEST_CASE```** and **```DOCTEST_SUBCASE```**. The user is free to make his own short versions of these macros - [**example**](../../examples/alternative_macros/)
-
-- **```DOCTEST_CONFIG_NO_UNPREFIXED_OPTIONS```** - this will disable the short versions of the [**command line**](commandline.md) options and only the versions with ```-dt-``` prefix will be parsed by **doctest** - this is possible for easy interoperability with client command line option handling when the testing framework is integrated within a client codebase - so there are no clashes and so that the user can exclude everything starting with ```-dt-``` from their option parsing. This configuration option is relevant only for the source file where the library is implemented
-
-- **```DOCTEST_CONFIG_COLORS_NONE```** - this will remove support for colors in the console output of the framework. This configuration option is relevant only for the source file where the library is implemented
-
-- **```DOCTEST_CONFIG_COLORS_WINDOWS```** - this will force the support for colors in the console output to use the Windows APIs and headers. This configuration option is relevant only for the source file where the library is implemented
-
-- **```DOCTEST_CONFIG_COLORS_ANSI```** - this will force the support for colors in the console output to use ANSI escape codes. This configuration option is relevant only for the source file where the library is implemented
-
-- **```DOCTEST_CONFIG_USE_IOSFWD```** - the library by default provides a forward declaration of ```std::ostream``` in order to support the ```operator<<``` [**stringification**](stringification.md) mechanism. This is forbidden by the standard (even though it works everywhere on all tested compilers). However if the user wishes to be 100% standards compliant - then this configuration option can be used to force the inclusion of ```<iosfwd>```. It should be defined everywhere before the framework header is included.
-
-- **```DOCTEST_CONFIG_WITH_LONG_LONG```** - by default the library includes support for stringifying ```long long``` only if the value of ```__cplusplus``` is at least ```201103L``` (C++11) or if the compiler is MSVC 2003 or newer. Many compilers that don't fully support C++11 have it as an extension but it errors for GCC/Clang when the ```-std=c++98``` option is used and this cannot be detected with the preprocessor in any way. Use this configuration option if your compiler supports ```long long``` but doesn't yet support the full C++11 standard. It should be defined everywhere before the framework header is included.
-
----------------
-
-[Home](readme.md#reference)
+## Configuration
+
+**doctest** is designed to "just work" as much as possible. It exposes a small set of defines for configuring how it is built.
+
+For most people the only configuration needed is telling **doctest** which source file should host all the implementation code:
+
+- **```DOCTEST_CONFIG_IMPLEMENT_WITH_MAIN```**
+
+ ```c++
+#define DOCTEST_CONFIG_IMPLEMENT_WITH_MAIN
+#include "doctest.h"
+ ```
+
+ This should be done in only one source file! Otherwise there will be linker errors and slower build times.
+
+- **```DOCTEST_CONFIG_IMPLEMENT```** - if the client wants to [**supply the ```main()``` function**](main.md) (either to set an option with some value from the code or to integrate the framework into his existing project codebase) this define should be used.
+
+- **```DOCTEST_CONFIG_DISABLE```** - the next most important configuration option - when defined globally in the whole project before the inclusion of the framework header - everything testing - related is removed from the binary - including most of the framework implementation and every test case written anywhere! This is one of the most unique features of **doctest**.
+
+- **```DOCTEST_CONFIG_NO_SHORT_MACRO_NAMES```** - this will remove all macros from **doctest** that don't have the **```DOCTEST_```** prefix - like **```CHECK```**, **```TEST_CASE```** and **```SUBCASE```**. Then only the full macro names will be available - **```DOCTEST_CHECK```**, **```DOCTEST_TEST_CASE```** and **```DOCTEST_SUBCASE```**. The user is free to make his own short versions of these macros - [**example**](../../examples/alternative_macros/)
+
+- **```DOCTEST_CONFIG_NO_UNPREFIXED_OPTIONS```** - this will disable the short versions of the [**command line**](commandline.md) options and only the versions with ```-dt-``` prefix will be parsed by **doctest** - this is possible for easy interoperability with client command line option handling when the testing framework is integrated within a client codebase - so there are no clashes and so that the user can exclude everything starting with ```-dt-``` from their option parsing. This configuration option is relevant only for the source file where the library is implemented
+
+- **```DOCTEST_CONFIG_COLORS_NONE```** - this will remove support for colors in the console output of the framework. This configuration option is relevant only for the source file where the library is implemented
+
+- **```DOCTEST_CONFIG_COLORS_WINDOWS```** - this will force the support for colors in the console output to use the Windows APIs and headers. This configuration option is relevant only for the source file where the library is implemented
+
+- **```DOCTEST_CONFIG_COLORS_ANSI```** - this will force the support for colors in the console output to use ANSI escape codes. This configuration option is relevant only for the source file where the library is implemented
+
+- **```DOCTEST_CONFIG_USE_IOSFWD```** - the library by default provides a forward declaration of ```std::ostream``` in order to support the ```operator<<``` [**stringification**](stringification.md) mechanism. This is forbidden by the standard (even though it works everywhere on all tested compilers). However if the user wishes to be 100% standards compliant - then this configuration option can be used to force the inclusion of ```<iosfwd>```. It should be defined everywhere before the framework header is included.
+
+- **```DOCTEST_CONFIG_WITH_LONG_LONG```** - by default the library includes support for stringifying ```long long``` only if the value of ```__cplusplus``` is at least ```201103L``` (C++11) or if the compiler is MSVC 2003 or newer. Many compilers that don't fully support C++11 have it as an extension but it errors for GCC/Clang when the ```-std=c++98``` option is used and this cannot be detected with the preprocessor in any way. Use this configuration option if your compiler supports ```long long``` but doesn't yet support the full C++11 standard. It should be defined everywhere before the framework header is included.
+
+---------------
+
+[Home](readme.md#reference)
diff --git a/doc/markdown/faq.md b/doc/markdown/faq.md
index c0a743c..aa20f22 100644
--- a/doc/markdown/faq.md
+++ b/doc/markdown/faq.md
@@ -1,41 +1,41 @@
-## FAQ
-
-#TODO...
-
-- linker issues? Make sure you have instantiated the test runner in only one source file.
-
-- stringification issues - if operator<<(ostream for a type is visible only in one source file...
-
-- why no regex and only wildcards
-
-- tests are ran serially - no multi-threaded execution planned for now
-
-- mocking is not included because it is orthogonal to testing and a different third party library may be used for that (google mock)
-https://github.com/tpounds/mockitopp
-
-- linker errors for ```doctest::detail::...``` when using ```DOCTEST_CONFIG_DISABLE```
- solution: don't use anything from detail
-
-- property based testing - what it is and how to use it with doctest
-
-- tests in headers... might end up in different test suites - and only 1 of them will get registered? or might have ifdef-ed parts that get compiled differently based on how/where the header is included...... so not a good practice to write tests in header files
-
-- how subcases work - http://pastebin.com/rwghFzK4 - or look in the repo
-
-- why c++98? because.
-
-- will the library support checking for memory leaks? no. use tools like valgrind or the sanitizers.
-
-- mixing different versions of the framework within the same executable?
- - unfortunately what single header libraries like [stb](https://github.com/nothings/stb) are doing is not feasible with this library.
- - it could be done if tests are written only in source files where the library has been implemented with the ```DOCTEST_CONFIG_IMPLEMENT``` macro but that is very limiting.
-
-- is the VC++6 support full?
- - no
- - the stringification with ```ostream& operator<<(ostream&, myType)``` is disabled
- - comparing C strings will compare the pointers and not the actual strings
- - VC6 subcases not working - set a bounty on this: http://stackoverflow.com/questions/36940730/preprocessor-problems-with-vc6
-
----------------
-
-[Home](readme.md#reference)
+## FAQ
+
+#TODO...
+
+- linker issues? Make sure you have instantiated the test runner in only one source file.
+
+- stringification issues - if operator<<(ostream for a type is visible only in one source file...
+
+- why no regex and only wildcards
+
+- tests are ran serially - no multi-threaded execution planned for now
+
+- mocking is not included because it is orthogonal to testing and a different third party library may be used for that (google mock)
+https://github.com/tpounds/mockitopp
+
+- linker errors for ```doctest::detail::...``` when using ```DOCTEST_CONFIG_DISABLE```
+ solution: don't use anything from detail
+
+- property based testing - what it is and how to use it with doctest
+
+- tests in headers... might end up in different test suites - and only 1 of them will get registered? or might have ifdef-ed parts that get compiled differently based on how/where the header is included...... so not a good practice to write tests in header files
+
+- how subcases work - http://pastebin.com/rwghFzK4 - or look in the repo
+
+- why c++98? because.
+
+- will the library support checking for memory leaks? no. use tools like valgrind or the sanitizers.
+
+- mixing different versions of the framework within the same executable?
+ - unfortunately what single header libraries like [stb](https://github.com/nothings/stb) are doing is not feasible with this library.
+ - it could be done if tests are written only in source files where the library has been implemented with the ```DOCTEST_CONFIG_IMPLEMENT``` macro but that is very limiting.
+
+- is the VC++6 support full?
+ - no
+ - the stringification with ```ostream& operator<<(ostream&, myType)``` is disabled
+ - comparing C strings will compare the pointers and not the actual strings
+ - VC6 subcases not working - set a bounty on this: http://stackoverflow.com/questions/36940730/preprocessor-problems-with-vc6
+
+---------------
+
+[Home](readme.md#reference)
diff --git a/doc/markdown/features.md b/doc/markdown/features.md
index 8a0a539..1d32ce2 100644
--- a/doc/markdown/features.md
+++ b/doc/markdown/features.md
@@ -5,55 +5,55 @@
## Unintrusive (transparent):
- everything testing-related can be removed from the binary executable by defining the [**```DOCTEST_CONFIG_DISABLE```**](configuration.md) identifier
-- very small and easy to integrate - single header - less than 3k LOC in the implementation translation unit and less than 1.5k LOC everywhere else - **extremely** low footprint on compile times - see the [**benchmarks**](benchmarks.md)
-- doesn't drag any headers when included (except for in the translation unit where the library gets implemented)
+- very small and easy to integrate - single header - less than 3k LOC in the implementation translation unit and less than 1.5k LOC everywhere else - **extremely** low footprint on compile times - see the [**benchmarks**](benchmarks.md)
+- doesn't drag any headers when included (except for in the translation unit where the library gets implemented)
- everything is in the ```doctest``` namespace (and the implementation details are in a nested ```detail``` namespace)
- all macros have prefixes - some by default have unprefixed versions as well but that is optional - see [**configuration**](configuration.md)
-- 0 warnings even with the most aggresive flags (on all tested compilers!!!)
- - ```-Weverything -pedantic``` for **clang**
- - ```-Wall -Wextra -pedantic``` and **>> over 50 <<** other warnings **not** covered by these flags for **GCC**!!! - see [**here**](../../scripts/common.cmake#L59)
- - ```/W4``` for **MSVC** (```/Wall``` is too much there - even their own headers produce **thousands** of warnings with that option)
+- 0 warnings even with the most aggresive flags (on all tested compilers!!!)
+ - ```-Weverything -pedantic``` for **clang**
+ - ```-Wall -Wextra -pedantic``` and **>> over 50 <<** other warnings **not** covered by these flags for **GCC**!!! - see [**here**](../../scripts/common.cmake#L59)
+ - ```/W4``` for **MSVC** (```/Wall``` is too much there - even their own headers produce **thousands** of warnings with that option)
- doesn't error on unrecognized [**command line**](commandline.md) options and supports prefixes for interop with client command line parsing
- can set options [**procedurally**](main.md) and not deal with passing ```argc```/```argv``` from the command line
- doesn't leave warnings disabled after itself
-
-## Extremely portable:
+
+## Extremely portable:
- Standards compliant **C++98** code - should work with any **C++98** compiler
- tested with **GCC**: **4.4**, **4.5**, **4.6**, **4.7**, **4.8**, **4.9**, **5.0**
- tested with **Clang**: **3.4**, **3.5**, **3.6**, **3.7**, **3.8**
- tested with **MSVC**: **2008**, **2010**, **2012**, **2013**, **2015** (and even **VC++6** - that **18 year old compiler** from 1998!)
-- per-commit tested on **travis** and **appveyor** CI services
- - warnings as errors even on the most aggressive warning levels - see [**here**](../../scripts/common.cmake#L59)
- - all tests have their output compared to reference output of a previous known good run
+- per-commit tested on **travis** and **appveyor** CI services
+ - warnings as errors even on the most aggressive warning levels - see [**here**](../../scripts/common.cmake#L59)
+ - all tests have their output compared to reference output of a previous known good run
- all tests built and ran in **Debug**/**Release** and also in **32**/**64** bit modes
- - all tests ran through **valgrind** under **Linux**/**OSX**
- - all tests ran through **address** and **UB** sanitizers under **Linux**/**OSX**
+ - all tests ran through **valgrind** under **Linux**/**OSX**
+ - all tests ran through **address** and **UB** sanitizers under **Linux**/**OSX**
- tests are ran in a total of **180** different configurations on UNIX (Linux + OSX) on **travis** CI
- - tests are ran in a total of **18** different configurations on Windows on **appveyor** CI
+ - tests are ran in a total of **18** different configurations on Windows on **appveyor** CI
## Other features:
-- really easy to get started - it's just 1 header file - see the [**tutorial**](tutorial.md)
-- **very** light, unintrusive and portable - see the sections above - and also the [**benchmarks**](benchmarks.md)
-- offers a way to remove **everything** testing-related from the binary with the [**```DOCTEST_CONFIG_DISABLE```**](configuration.md) macro
-- tests are registered automatically - no need to add them to a collection manually
-- supports [**subcases**](testcases.md#subcases) for easy setup/teardown of tests (also supports the retro [**test fixtures**](testcases.md#test-fixtures) with classes)
-- output from all compilers on all platforms is the same - byte by byte
-- supports [**BDD style**](testcases.md##bdd-style-test-cases) tests
-- only one core [**assertion macro**](assertions.md) for comparisons - standard C++ operators are used for the comparison (less than, equal, greater than...) - yet the full expression is decomposed and left and right values of the expression are logged
-- assertion macros for [**exceptions**](assertions.md#exceptions) - if something should or shouldn't throw
-- floating point comparison support - see the [**```Approx()```**](assertions.md#floating-point-comparisons) helper
-- powerful mechanism for [**stringification**](stringification.md) of user types
+- really easy to get started - it's just 1 header file - see the [**tutorial**](tutorial.md)
+- **very** light, unintrusive and portable - see the sections above - and also the [**benchmarks**](benchmarks.md)
+- offers a way to remove **everything** testing-related from the binary with the [**```DOCTEST_CONFIG_DISABLE```**](configuration.md) macro
+- tests are registered automatically - no need to add them to a collection manually
+- supports [**subcases**](testcases.md#subcases) for easy setup/teardown of tests (also supports the retro [**test fixtures**](testcases.md#test-fixtures) with classes)
+- output from all compilers on all platforms is the same - byte by byte
+- supports [**BDD style**](testcases.md##bdd-style-test-cases) tests
+- only one core [**assertion macro**](assertions.md) for comparisons - standard C++ operators are used for the comparison (less than, equal, greater than...) - yet the full expression is decomposed and left and right values of the expression are logged
+- assertion macros for [**exceptions**](assertions.md#exceptions) - if something should or shouldn't throw
+- floating point comparison support - see the [**```Approx()```**](assertions.md#floating-point-comparisons) helper
+- powerful mechanism for [**stringification**](stringification.md) of user types
- tests can be grouped in [**test suites**](testcases.md#test-suites)
-- powerful [**command line**](commandline.md) with lots of options
-- tests can be [**filtered**](commandline.md) based on their name/file/test suite using wildcards
-- failures can (optionally) break into the debugger on Windows and Mac
-- integration with the output window of Visual Studio for failing tests
+- powerful [**command line**](commandline.md) with lots of options
+- tests can be [**filtered**](commandline.md) based on their name/file/test suite using wildcards
+- failures can (optionally) break into the debugger on Windows and Mac
+- integration with the output window of Visual Studio for failing tests
- a ```main()``` can be provided when implementing the library with the [**```DOCTEST_CONFIG_IMPLEMENT_WITH_MAIN```**](main.md) identifier
-- can write tests in headers - they will still be registered only once in the executable/shared object
-- [**range-based**](commandline.md) execution of tests - see the [**range_based_execution**](../../examples/range_based_execution/) example (the **run.py** script)
-- colored output in the console
+- can write tests in headers - they will still be registered only once in the executable/shared object
+- [**range-based**](commandline.md) execution of tests - see the [**range_based_execution**](../../examples/range_based_execution/) example (the **run.py** script)
+- colored output in the console
- controlling the order of test execution
There is a list of planned features which are all important and big - see the [**roadmap**](roadmap.md).
diff --git a/doc/markdown/main.md b/doc/markdown/main.md
index bb8e3f0..6a48ef9 100644
--- a/doc/markdown/main.md
+++ b/doc/markdown/main.md
@@ -1,52 +1,52 @@
-## The ```main()``` entry point
-
-The usual way of writing tests in C++ has always been into separate source files from the code they test that form an executable containing only tests. In that scenario the default ```main()``` provided by **doctest** is usually sufficient:
-
-```c++
-#define DOCTEST_CONFIG_IMPLEMENT_WITH_MAIN
-#include "doctest.h"
-```
-
-This should be done in exactly one source file and is even a good idea to do this in a separate file with nothing else in it.
-
-However if you need more control - want to set options with code to the execution context or want to integrate the framework in your production code - then the default ```main()``` just won't do the job. In that case use **```DOCTEST_CONFIG_IMPLEMENT```**.
-
-All the [**command line**](commandline.md) options can be set like this (flags cannot because it wouldn't make sense). Filters can only be appended - the user cannot remove a filter given from the command line with code.
-
-```c++
-#define DOCTEST_CONFIG_IMPLEMENT
-#include "doctest.h"
-
-int main(int argc, char** argv) {
- doctest::Context context(argc, argv); // initialize
-
- // overrides
- context.addFilter("test-case-exclude", "*math*"); // exclude test cases with "math" in their name
- context.setOption("no-breaks", true); // don't break in the debugger when assertions fail
- context.setOption("abort-after", 5); // stop test execution after 5 failed assertions
- context.setOption("sort", "name"); // sort the test cases by their name
-
- int res = context.run(); // run
-
- if(context.shouldExit()) // important - query flags (and --no-run) rely on the user doing this
- return res; // propagate the result of the tests
-
- int client_stuff_return_code = 0;
- // your program - if the testing framework is integrated in your production code
-
- return res + client_stuff_return_code;
-}
-
-```
-
-Note the call to ```.shouldExit()``` on the context - that is very important - it will be set when a query flag has been used (or the ```--no-run``` option is set to ```true```) and it is the user's responsibility to exit the application in a normal way.
-
-### Dealing with shared objects (DLLs)
-
-When integrating the framework in production code which gets built as a shared object (dll) everything still works. Many shared objects and an executable can have tests in them and can even use different versions of the **doctest** framework.
-
-Check out [**this**](../../examples/dll_and_executable/) example which showcases how to call the tests in a shared object from the executable (and it also showcases that if a file with a test case is included both in the shared object and the executable then the test is registered in both places).
-
----------------
-
-[Home](readme.md#reference)
+## The ```main()``` entry point
+
+The usual way of writing tests in C++ has always been into separate source files from the code they test that form an executable containing only tests. In that scenario the default ```main()``` provided by **doctest** is usually sufficient:
+
+```c++
+#define DOCTEST_CONFIG_IMPLEMENT_WITH_MAIN
+#include "doctest.h"
+```
+
+This should be done in exactly one source file and is even a good idea to do this in a separate file with nothing else in it.
+
+However if you need more control - want to set options with code to the execution context or want to integrate the framework in your production code - then the default ```main()``` just won't do the job. In that case use **```DOCTEST_CONFIG_IMPLEMENT```**.
+
+All the [**command line**](commandline.md) options can be set like this (flags cannot because it wouldn't make sense). Filters can only be appended - the user cannot remove a filter given from the command line with code.
+
+```c++
+#define DOCTEST_CONFIG_IMPLEMENT
+#include "doctest.h"
+
+int main(int argc, char** argv) {
+ doctest::Context context(argc, argv); // initialize
+
+ // overrides
+ context.addFilter("test-case-exclude", "*math*"); // exclude test cases with "math" in their name
+ context.setOption("no-breaks", true); // don't break in the debugger when assertions fail
+ context.setOption("abort-after", 5); // stop test execution after 5 failed assertions
+ context.setOption("sort", "name"); // sort the test cases by their name
+
+ int res = context.run(); // run
+
+ if(context.shouldExit()) // important - query flags (and --no-run) rely on the user doing this
+ return res; // propagate the result of the tests
+
+ int client_stuff_return_code = 0;
+ // your program - if the testing framework is integrated in your production code
+
+ return res + client_stuff_return_code;
+}
+
+```
+
+Note the call to ```.shouldExit()``` on the context - that is very important - it will be set when a query flag has been used (or the ```--no-run``` option is set to ```true```) and it is the user's responsibility to exit the application in a normal way.
+
+### Dealing with shared objects (DLLs)
+
+When integrating the framework in production code which gets built as a shared object (dll) everything still works. Many shared objects and an executable can have tests in them and can even use different versions of the **doctest** framework.
+
+Check out [**this**](../../examples/dll_and_executable/) example which showcases how to call the tests in a shared object from the executable (and it also showcases that if a file with a test case is included both in the shared object and the executable then the test is registered in both places).
+
+---------------
+
+[Home](readme.md#reference)
diff --git a/doc/markdown/readme.md b/doc/markdown/readme.md
index 3f28e8c..d803d51 100644
--- a/doc/markdown/readme.md
+++ b/doc/markdown/readme.md
@@ -1,22 +1,22 @@
Reference
=======
-- [Features and design goals](features.md) - the complete list of features
-- [Roadmap](roadmap.md) - upcoming features
-- [Tutorial](tutorial.md) - make sure you have read it before the other parts of the documentation
-- [Benchmarks](benchmarks.md) - compile time supremacy
-- [Examples](../../examples)
-
--------------
-
-- [Assertion macros](assertions.md)
-- [Test cases, subcases and test fixtures](testcases.md)
-- [Command line](commandline.md)
-- [Configuration](configuration.md)
-- [String conversions](stringification.md)
-- [```main()``` entry point and dealing with shared objects](main.md)
-- [FAQ](faq.md)
-
-Support the development of the project with donations! There is a list of planned features which are all important and big - see the [**roadmap**](roadmap.md). I work on this project in my spare time and every cent is a big deal.
-
+- [Features and design goals](features.md) - the complete list of features
+- [Roadmap](roadmap.md) - upcoming features
+- [Tutorial](tutorial.md) - make sure you have read it before the other parts of the documentation
+- [Benchmarks](benchmarks.md) - compile time supremacy
+- [Examples](../../examples)
+
+-------------
+
+- [Assertion macros](assertions.md)
+- [Test cases, subcases and test fixtures](testcases.md)
+- [Command line](commandline.md)
+- [Configuration](configuration.md)
+- [String conversions](stringification.md)
+- [```main()``` entry point and dealing with shared objects](main.md)
+- [FAQ](faq.md)
+
+Support the development of the project with donations! There is a list of planned features which are all important and big - see the [**roadmap**](roadmap.md). I work on this project in my spare time and every cent is a big deal.
+
[![Donate to support](https://pledgie.com/campaigns/31280.png)](https://pledgie.com/campaigns/31280)
\ No newline at end of file
diff --git a/doc/markdown/roadmap.md b/doc/markdown/roadmap.md
index 4b0a25a..bff3bd8 100644
--- a/doc/markdown/roadmap.md
+++ b/doc/markdown/roadmap.md
@@ -11,24 +11,24 @@
- support for ```std::exception``` and derivatives (mainly for calling the ```.what()``` method when caught unexpectedly)
- test with missed warning flags for GCC - look into https://github.com/Barro/compiler-warnings
- crash handling: signals on UNIX platforms or structured exceptions on Windows
-- support for tags
- - may fail tag
- - invisible tag
+- support for tags
+ - may fail tag
+ - invisible tag
- look at Catch - https://github.com/philsquared/Catch/blob/master/docs/test-cases-and-sections.md#special-tags
-- output to file
-- reporters
- - a system for writing custom reporters
+- output to file
+- reporters
+ - a system for writing custom reporters
- ability to use multiple reporters at once (but only 1 to stdout)
- - a compact reporter
- - an xml reporter
+ - a compact reporter
+ - an xml reporter
- jUnit/xUnit reporters
-- add the ability to query if code is currently being ran in a test - ```doctest::isRunningInTest()```
-- convolution support for the assertion macros (with a predicate)
-- time stuff
- - reporting running time of tests
- - restricting duration of test cases
- - killing a test that exceeds a time limit (will perhaps require threading or processes)
-- adding contextual info to asserts (logging) - with an ```INFO```/```CONTEXT``` /```TRACEPOINT``` macro
+- add the ability to query if code is currently being ran in a test - ```doctest::isRunningInTest()```
+- convolution support for the assertion macros (with a predicate)
+- time stuff
+ - reporting running time of tests
+ - restricting duration of test cases
+ - killing a test that exceeds a time limit (will perhaps require threading or processes)
+- adding contextual info to asserts (logging) - with an ```INFO```/```CONTEXT``` /```TRACEPOINT``` macro
- add ```ERROR```/```FAIL``` macros
- running tests a few times
- marking a test to run X times (should also multiply with the global test run times)
@@ -46,9 +46,9 @@
- handle ```wchar``` strings
- refactor the assertion macros - make proxy functions that do most of the things to minimize code bloat
- pool allocator for the ```String``` class - currently very unoptimized
-- ability to specify ASC/DESC for the order option
+- ability to specify ASC/DESC for the order option
- command line error handling/reporting
-- utf8? not sure if this should be here
+- utf8? not sure if this should be here
- print a warning when no assertion is encountered in a test case
- hierarchical test suites - using a stack for the pushed ones - should be easy
- put everything from the ```detail``` namespace also in a nested anonymous namespace to make them with internal linkage
diff --git a/doc/markdown/stringification.md b/doc/markdown/stringification.md
index c26e6e5..6c495ae 100644
--- a/doc/markdown/stringification.md
+++ b/doc/markdown/stringification.md
@@ -1,66 +1,66 @@
-## String conversions
-
-**doctest** needs to be able to convert types you use in assertions and logging expressions into strings (for logging and reporting purposes).
-Most built-in types are supported out of the box but there are three ways that you can tell **doctest** 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:
-
-```c++
-std::ostream& operator<< (std::ostream& os, const T& 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.
-
-Alternatively you may prefer to write it as a member function:
-
-```c++
-std::ostream& T::operator<<(std::ostream& os) const {
- os << convertMyTypeToString(*this);
- return os;
-}
-```
-
-## ```doctest::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 ```doctest::toString()``` for your type.
-
-```c++
-namespace doctest {
- String toString(const T& 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 **doctest** namespace which itself must be in the global namespace.
-
-## ```doctest::StringMaker<T>``` specialisation
-
-There are some cases where overloading ```toString``` does not work as expected. Specialising ```StringMaker<T>``` gives you more precise and reliable control - but at the cost of slightly more code and complexity:
-
-```c++
-namespace doctest {
- template<> struct StringMaker<T> {
- static String convert(const T& value) {
- return convertMyTypeToString(value);
- }
- };
-}
-```
-
-------
-
-- Check out the [**example**](../../examples/stringification/main.cpp) which shows how to stringify ```std::vector<T>``` and other types.
-- Note that the type ```String``` is used when specializing ```StringMaker<T>``` or overloading ```toString()``` - it is the string type **doctest** works with. ```std::string``` is not an option for the library because then it would have to drag the ```<string>``` header with it.
-- To support the ```operator<<(std::ostream&...``` stringification the library has to offer a forward declaration of ```std::ostream``` and that is what the library does - but it is forbidden by the standard. It currently works everywhere - on all tested compilers - but if the user wishes to be 100% standards compliant - then the [**```DOCTEST_CONFIG_USE_IOSFWD```**](configuration.md) identifier can be used to force the inclusion of ```<iosfwd>```. The reason the header is not included by default is that on MSVC (for example) it drags a whole bunch of stuff with it - and after the preprocessor is finished the translation unit has grown to 42k lines of C++ code - while Clang and the libc++ are so well implemented that including ```<iosfwd>``` there results in 400 lines of code.
-
----
-
-[Home](readme.md#reference)
+## String conversions
+
+**doctest** needs to be able to convert types you use in assertions and logging expressions into strings (for logging and reporting purposes).
+Most built-in types are supported out of the box but there are three ways that you can tell **doctest** 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:
+
+```c++
+std::ostream& operator<< (std::ostream& os, const T& 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.
+
+Alternatively you may prefer to write it as a member function:
+
+```c++
+std::ostream& T::operator<<(std::ostream& os) const {
+ os << convertMyTypeToString(*this);
+ return os;
+}
+```
+
+## ```doctest::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 ```doctest::toString()``` for your type.
+
+```c++
+namespace doctest {
+ String toString(const T& 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 **doctest** namespace which itself must be in the global namespace.
+
+## ```doctest::StringMaker<T>``` specialisation
+
+There are some cases where overloading ```toString``` does not work as expected. Specialising ```StringMaker<T>``` gives you more precise and reliable control - but at the cost of slightly more code and complexity:
+
+```c++
+namespace doctest {
+ template<> struct StringMaker<T> {
+ static String convert(const T& value) {
+ return convertMyTypeToString(value);
+ }
+ };
+}
+```
+
+------
+
+- Check out the [**example**](../../examples/stringification/main.cpp) which shows how to stringify ```std::vector<T>``` and other types.
+- Note that the type ```String``` is used when specializing ```StringMaker<T>``` or overloading ```toString()``` - it is the string type **doctest** works with. ```std::string``` is not an option for the library because then it would have to drag the ```<string>``` header with it.
+- To support the ```operator<<(std::ostream&...``` stringification the library has to offer a forward declaration of ```std::ostream``` and that is what the library does - but it is forbidden by the standard. It currently works everywhere - on all tested compilers - but if the user wishes to be 100% standards compliant - then the [**```DOCTEST_CONFIG_USE_IOSFWD```**](configuration.md) identifier can be used to force the inclusion of ```<iosfwd>```. The reason the header is not included by default is that on MSVC (for example) it drags a whole bunch of stuff with it - and after the preprocessor is finished the translation unit has grown to 42k lines of C++ code - while Clang and the libc++ are so well implemented that including ```<iosfwd>``` there results in 400 lines of code.
+
+---
+
+[Home](readme.md#reference)
diff --git a/doc/markdown/testcases.md b/doc/markdown/testcases.md
index f8a02ce..9c0048c 100644
--- a/doc/markdown/testcases.md
+++ b/doc/markdown/testcases.md
@@ -1,98 +1,98 @@
-## Test cases
-
-While **doctest** fully supports the traditional, xUnit, style of class-based fixtures containing test case methods this is not the preferred style.
-
-Instead **doctest** provides a powerful mechanism for nesting subcases within a test case. For a more detailed discussion see the [**tutorial**](tutorial.md#test-cases-and-subcases).
-
-Test cases and subcases are very easy to use in practice:
-
-* **TEST_CASE(** _test name_ **)**
-* **SUBCASE(** _subcase name_ **)**
-
-_test name_ and _subcase name_ are free form, quoted, strings. Test names don't have to be unique within the **doctest** executable. They should also be string literals.
-
-For examples see the [Tutorial](tutorial.md)
-
-## BDD-style test cases
-
-In addition to **doctest**'s take on the classic style of test cases, **doctest** 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 ```SUBCASE```s, with a little internal support to make them smoother to work with.
-
-* **SCENARIO(** _scenario name_ **)**
-
-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 ```SUBCASE```s except that the subcase 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 ```SUBCASE```s. As such there is nothing enforcing the correct sequencing of these macros - that's up to the programmer!
-
-## Test fixtures
-
-Although **doctest** allows you to group tests together as subcases within a test case, it can still be convenient, sometimes, to group them using a more traditional test fixture. **doctest** 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_FIXTURE(UniqueTestsFixture, "Create Employee/No Name") {
- REQUIRE_THROWS(conn.executeSQL("INSERT INTO employee (id, name) VALUES (?, ?)", getID(), ""));
- }
- TEST_CASE_METHOD(UniqueTestsFixture, "Create Employee/Normal") {
- 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.
-
-## Test suites
-
-Test cases can be grouped into test suites. This is done with the ```TEST_SUITE()``` and ```TEST_SUITE_END()``` macros.
-
-For example:
-
-```c++
-TEST_CASE("") {} // not part of any test suite
-
-TEST_SUITE("math");
-
-TEST_CASE("") {} // part of the math test suite
-TEST_CASE("") {} // part of the math test suite
-
-TEST_SUITE_END();
-
-TEST_CASE("") {} // not part of any test suite
-```
-
-Then test cases from specific test suites can be executed with the help of filters - check out the [**command line**](commandline.md)
-
-------
-
-- Check out the [**example**](../../examples/subcases_and_bdd/main.cpp)
-- Tests are registered from top to bottom of each processed cpp after the headers have been preprocessed and included but there is no ordering between cpp files.
-
----------------
-
-[Home](readme.md#reference)
+## Test cases
+
+While **doctest** fully supports the traditional, xUnit, style of class-based fixtures containing test case methods this is not the preferred style.
+
+Instead **doctest** provides a powerful mechanism for nesting subcases within a test case. For a more detailed discussion see the [**tutorial**](tutorial.md#test-cases-and-subcases).
+
+Test cases and subcases are very easy to use in practice:
+
+* **TEST_CASE(** _test name_ **)**
+* **SUBCASE(** _subcase name_ **)**
+
+_test name_ and _subcase name_ are free form, quoted, strings. Test names don't have to be unique within the **doctest** executable. They should also be string literals.
+
+For examples see the [Tutorial](tutorial.md)
+
+## BDD-style test cases
+
+In addition to **doctest**'s take on the classic style of test cases, **doctest** 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 ```SUBCASE```s, with a little internal support to make them smoother to work with.
+
+* **SCENARIO(** _scenario name_ **)**
+
+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 ```SUBCASE```s except that the subcase 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 ```SUBCASE```s. As such there is nothing enforcing the correct sequencing of these macros - that's up to the programmer!
+
+## Test fixtures
+
+Although **doctest** allows you to group tests together as subcases within a test case, it can still be convenient, sometimes, to group them using a more traditional test fixture. **doctest** 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_FIXTURE(UniqueTestsFixture, "Create Employee/No Name") {
+ REQUIRE_THROWS(conn.executeSQL("INSERT INTO employee (id, name) VALUES (?, ?)", getID(), ""));
+ }
+ TEST_CASE_METHOD(UniqueTestsFixture, "Create Employee/Normal") {
+ 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.
+
+## Test suites
+
+Test cases can be grouped into test suites. This is done with the ```TEST_SUITE()``` and ```TEST_SUITE_END()``` macros.
+
+For example:
+
+```c++
+TEST_CASE("") {} // not part of any test suite
+
+TEST_SUITE("math");
+
+TEST_CASE("") {} // part of the math test suite
+TEST_CASE("") {} // part of the math test suite
+
+TEST_SUITE_END();
+
+TEST_CASE("") {} // not part of any test suite
+```
+
+Then test cases from specific test suites can be executed with the help of filters - check out the [**command line**](commandline.md)
+
+------
+
+- Check out the [**example**](../../examples/subcases_and_bdd/main.cpp)
+- Tests are registered from top to bottom of each processed cpp after the headers have been preprocessed and included but there is no ordering between cpp files.
+
+---------------
+
+[Home](readme.md#reference)
diff --git a/doc/markdown/tutorial.md b/doc/markdown/tutorial.md
index 0a762e9..982d40b 100644
--- a/doc/markdown/tutorial.md
+++ b/doc/markdown/tutorial.md
@@ -1,208 +1,208 @@
-## Tutorial
-
-To get started with **doctest** all you need is to download the [**latest version**](https://raw.githubusercontent.com/onqtam/doctest/master/doctest/doctest.h) which is just a single header and include it in your source files (or add this repository as a git submodule).
-
-This tutorial assumes you can use the header directly: ```#include "doctest.h"``` - so it is either in the same folder with your test source files or you have set up the include paths to it in your build system properly.
-
-[TDD](https://en.wikipedia.org/wiki/Test-driven_development) is not discussed in this tutorial.
-
-## A simple example
-
-Suppose we have a ```factorial()``` function that we want to test:
-
-```c++
-int factorial(int number) { return number <= 1 ? number : factorial(number - 1) * number; }
-```
-
-A complete compiling example with a self-registering test looks like this:
-
-```c++
-#define DOCTEST_CONFIG_IMPLEMENT_WITH_MAIN
-#include "doctest.h"
-
-int factorial(int number) { return number <= 1 ? number : factorial(number - 1) * number; }
-
-TEST_CASE("testing the factorial function") {
- CHECK(factorial(1) == 1);
- CHECK(factorial(2) == 2);
- CHECK(factorial(3) == 6);
- CHECK(factorial(10) == 3628800);
-}
-```
-
-This will compile to a complete executable which responds to command line arguments. If you just run it with no arguments it will execute all test cases (in this case - just one), report any failures, report a summary of how many tests passed and failed and returns 0 on success and 1 if anything failed (useful 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. We missed to check if ```factorial(0) == 1``` so lets add that check as well:
-
-```c++
-TEST_CASE("testing the factorial function") {
- CHECK(factorial(0) == 1);
- CHECK(factorial(1) == 1);
- CHECK(factorial(2) == 2);
- CHECK(factorial(3) == 6);
- CHECK(factorial(10) == 3628800);
-}
-```
-
-Now we get a failure - something like:
-
-```
-test.cpp(7) FAILED!
- CHECK( factorial(0) == 1 )
-with expansion:
- CHECK( 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 let's us immediately see what the problem is.
-
-Let's change the factorial function to:
-
-```c++
-int factorial(int number) { return number > 1 ? factorial(number - 1) * number : 1; }
-```
-
-Now all the tests pass.
-
-Of course there are still more issues to do deal with. For example we'll hit problems when the return value starts to exceed the range of an 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 **doctest** is used.
-
-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. You can only use that ```#define``` in one source file for (hopefully) obvious reasons. Once you have more than one file with unit tests in you'll just ```#include "doctest.h"``` and go. Usually it's a good idea to have a dedicated implementation file that just has ```#define DOCTEST_CONFIG_IMPLEMENT_WITH_MAIN``` and ```#include "doctest.h"```. You can also provide your own implementation of main and drive **doctest** yourself - see [**supplying your own ```main()```**](main.md).
-2. We introduce test cases with the ```TEST_CASE``` macro. It takes one argument - a free form test name (for more see [**Test cases and subcases**](testcases.md)). The test name doesn't have to be unique. You can run sets of tests by specifying a wildcarded test name or a tag expression. See the [**command line**](commandline.md) docs for more information on running tests.
-3. The name is just a string. 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 ```CHECK()``` macro. Rather than a separate macro for each type of condition (equal, less than, greater than, etc.) we express the condition naturally using C++ syntax. Behind the scenes a simple expression template captures the left-hand-side and right-hand-side of the expression so we can display the values in our test report. There are other [**assertion macros**](assertions.md) not covered in this tutorial - but because of this technique the number of them is drastically reduced.
-
-## Test cases and subcases
-
-Most test frameworks have a class-based fixture mechanism - 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 **doctest** 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**](http://jamesnewkirk.typepad.com/posts/2007/09/why-you-should-.html) that led James Newkirk who led the team that built NUnit to start again from scratch and build [**xUnit**](http://jamesnewkirk.typepad.com/posts/2007/09/announcing-xuni.html)).
-
-**doctest** 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") {
- std::vector<int> v(5);
-
- REQUIRE(v.size() == 5);
- REQUIRE(v.capacity() >= 5);
-
- SUBCASE("adding to the vector increases it's size") {
- v.push_back(1);
-
- CHECK(v.size() == 6);
- CHECK(v.capacity() >= 6);
- }
- SUBCASE("reserving increases just the capacity") {
- v.reserve(6);
-
- CHECK(v.size() == 5);
- CHECK(v.capacity() >= 6);
- }
-}
-```
-
-For each ```SUBCASE()``` the ```TEST_CASE()``` is executed from the start - so as we enter each subcase we know that the size is 5 and the capacity is at least 5. We enforce those requirements with the ```REQUIRE()``` macros at the top level so we can be confident in them. If a ```CHECK()``` fails - the test is marked as failed but the execution continues - but if a ```REQUIRE()``` fails - execution of the test stops.
-
-This works because the ```SUBCASE()``` macro contains an if statement that calls back into **doctest** to see if the subcase should be executed. One leaf subcase is executed on each run through a ```TEST_CASE()```. The other subcases are skipped. Next time the next subcase is executed and so on until no new subcases 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 subcases really shows when we start nesting them like in the example below:
-
-<table><tr><td>
-Code
-</td><td>
-Output
-</td></tr><tr><td>
-<pre lang="c++">
-#define DOCTEST_CONFIG_IMPLEMENT_WITH_MAIN
-#include "doctest.h"
-
-#include <iostream>
-using namespace std;
-
-TEST_CASE("lots of nested subcases") {
- cout << endl << "root" << endl;
- SUBCASE("") {
- cout << "1" << endl;
- SUBCASE("") { cout << "1.1" << endl; }
- }
- SUBCASE("") {
- cout << "2" << endl;
- SUBCASE("") { cout << "2.1" << endl; }
- SUBCASE("") {
- cout << "2.2" << endl;
- SUBCASE("") {
- cout << "2.2.1" << endl;
- SUBCASE("") { cout << "2.2.1.1" << endl; }
- SUBCASE("") { cout << "2.2.1.2" << endl; }
- }
- }
- SUBCASE("") { cout << "2.3" << endl; }
- SUBCASE("") { cout << "2.4" << endl; }
- }
-}
-</pre>
-</td><td>
-<pre lang="">
-root
-1
-1.1
-
-root
-2
-2.1
-
-root
-2
-2.2
-2.2.1
-2.2.1.1
-
-root
-2
-2.2
-2.2.1
-2.2.1.2
-
-root
-2
-2.3
-
-root
-2
-2.4
-</pre>
-</td></tr></table>
-
-Subcases can be nested to an arbitrary depth (limited only by your stack size). Each leaf subcase (a subcase that contains no nested subcases) will be executed exactly once on a separate path of execution from any other leaf subcase (so no leaf subcase can interfere with another). A fatal failure in a parent subcase will prevent nested subcases from running - but then that's the idea.
-
-You can check out how subcases are implemented in [**this example**](../../scripts/how_subcases_work/main.cpp#L1).
-
-## 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 **doctest** even quicker and easier. This is not really the best approach when you start writing more real-world tests.
-
-The requirement is that the following block of code ([**or equivalent**](main.md)):
-
-```c++
-#define DOCTEST_CONFIG_IMPLEMENT_WITH_MAIN
-#include "doctest.h"
-```
-
-appears in _exactly_ one translation unit (source file). Use as many additional source files as you need for your tests - partitioned however makes most sense for your way of working. Each additional file needs only to ```#include "doctest.h"``` - do not repeat the ```#define```!
-
-In fact it is usually a good idea to put the block with the ```#define``` in it's own source file.
-
-## Next steps
-
-This has been a brief introduction to get you up and running with **doctest** and to point out some of the key differences between **doctest** 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 - see the ever-growing [**reference**](readme.md#reference) section for what's available.
-
----------------
-
-[Home](readme.md#reference)
+## Tutorial
+
+To get started with **doctest** all you need is to download the [**latest version**](https://raw.githubusercontent.com/onqtam/doctest/master/doctest/doctest.h) which is just a single header and include it in your source files (or add this repository as a git submodule).
+
+This tutorial assumes you can use the header directly: ```#include "doctest.h"``` - so it is either in the same folder with your test source files or you have set up the include paths to it in your build system properly.
+
+[TDD](https://en.wikipedia.org/wiki/Test-driven_development) is not discussed in this tutorial.
+
+## A simple example
+
+Suppose we have a ```factorial()``` function that we want to test:
+
+```c++
+int factorial(int number) { return number <= 1 ? number : factorial(number - 1) * number; }
+```
+
+A complete compiling example with a self-registering test looks like this:
+
+```c++
+#define DOCTEST_CONFIG_IMPLEMENT_WITH_MAIN
+#include "doctest.h"
+
+int factorial(int number) { return number <= 1 ? number : factorial(number - 1) * number; }
+
+TEST_CASE("testing the factorial function") {
+ CHECK(factorial(1) == 1);
+ CHECK(factorial(2) == 2);
+ CHECK(factorial(3) == 6);
+ CHECK(factorial(10) == 3628800);
+}
+```
+
+This will compile to a complete executable which responds to command line arguments. If you just run it with no arguments it will execute all test cases (in this case - just one), report any failures, report a summary of how many tests passed and failed and returns 0 on success and 1 if anything failed (useful 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. We missed to check if ```factorial(0) == 1``` so lets add that check as well:
+
+```c++
+TEST_CASE("testing the factorial function") {
+ CHECK(factorial(0) == 1);
+ CHECK(factorial(1) == 1);
+ CHECK(factorial(2) == 2);
+ CHECK(factorial(3) == 6);
+ CHECK(factorial(10) == 3628800);
+}
+```
+
+Now we get a failure - something like:
+
+```
+test.cpp(7) FAILED!
+ CHECK( factorial(0) == 1 )
+with expansion:
+ CHECK( 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 let's us immediately see what the problem is.
+
+Let's change the factorial function to:
+
+```c++
+int factorial(int number) { return number > 1 ? factorial(number - 1) * number : 1; }
+```
+
+Now all the tests pass.
+
+Of course there are still more issues to do deal with. For example we'll hit problems when the return value starts to exceed the range of an 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 **doctest** is used.
+
+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. You can only use that ```#define``` in one source file for (hopefully) obvious reasons. Once you have more than one file with unit tests in you'll just ```#include "doctest.h"``` and go. Usually it's a good idea to have a dedicated implementation file that just has ```#define DOCTEST_CONFIG_IMPLEMENT_WITH_MAIN``` and ```#include "doctest.h"```. You can also provide your own implementation of main and drive **doctest** yourself - see [**supplying your own ```main()```**](main.md).
+2. We introduce test cases with the ```TEST_CASE``` macro. It takes one argument - a free form test name (for more see [**Test cases and subcases**](testcases.md)). The test name doesn't have to be unique. You can run sets of tests by specifying a wildcarded test name or a tag expression. See the [**command line**](commandline.md) docs for more information on running tests.
+3. The name is just a string. 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 ```CHECK()``` macro. Rather than a separate macro for each type of condition (equal, less than, greater than, etc.) we express the condition naturally using C++ syntax. Behind the scenes a simple expression template captures the left-hand-side and right-hand-side of the expression so we can display the values in our test report. There are other [**assertion macros**](assertions.md) not covered in this tutorial - but because of this technique the number of them is drastically reduced.
+
+## Test cases and subcases
+
+Most test frameworks have a class-based fixture mechanism - 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 **doctest** 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**](http://jamesnewkirk.typepad.com/posts/2007/09/why-you-should-.html) that led James Newkirk who led the team that built NUnit to start again from scratch and build [**xUnit**](http://jamesnewkirk.typepad.com/posts/2007/09/announcing-xuni.html)).
+
+**doctest** 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") {
+ std::vector<int> v(5);
+
+ REQUIRE(v.size() == 5);
+ REQUIRE(v.capacity() >= 5);
+
+ SUBCASE("adding to the vector increases it's size") {
+ v.push_back(1);
+
+ CHECK(v.size() == 6);
+ CHECK(v.capacity() >= 6);
+ }
+ SUBCASE("reserving increases just the capacity") {
+ v.reserve(6);
+
+ CHECK(v.size() == 5);
+ CHECK(v.capacity() >= 6);
+ }
+}
+```
+
+For each ```SUBCASE()``` the ```TEST_CASE()``` is executed from the start - so as we enter each subcase we know that the size is 5 and the capacity is at least 5. We enforce those requirements with the ```REQUIRE()``` macros at the top level so we can be confident in them. If a ```CHECK()``` fails - the test is marked as failed but the execution continues - but if a ```REQUIRE()``` fails - execution of the test stops.
+
+This works because the ```SUBCASE()``` macro contains an if statement that calls back into **doctest** to see if the subcase should be executed. One leaf subcase is executed on each run through a ```TEST_CASE()```. The other subcases are skipped. Next time the next subcase is executed and so on until no new subcases 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 subcases really shows when we start nesting them like in the example below:
+
+<table><tr><td>
+Code
+</td><td>
+Output
+</td></tr><tr><td>
+<pre lang="c++">
+#define DOCTEST_CONFIG_IMPLEMENT_WITH_MAIN
+#include "doctest.h"
+
+#include <iostream>
+using namespace std;
+
+TEST_CASE("lots of nested subcases") {
+ cout << endl << "root" << endl;
+ SUBCASE("") {
+ cout << "1" << endl;
+ SUBCASE("") { cout << "1.1" << endl; }
+ }
+ SUBCASE("") {
+ cout << "2" << endl;
+ SUBCASE("") { cout << "2.1" << endl; }
+ SUBCASE("") {
+ cout << "2.2" << endl;
+ SUBCASE("") {
+ cout << "2.2.1" << endl;
+ SUBCASE("") { cout << "2.2.1.1" << endl; }
+ SUBCASE("") { cout << "2.2.1.2" << endl; }
+ }
+ }
+ SUBCASE("") { cout << "2.3" << endl; }
+ SUBCASE("") { cout << "2.4" << endl; }
+ }
+}
+</pre>
+</td><td>
+<pre lang="">
+root
+1
+1.1
+
+root
+2
+2.1
+
+root
+2
+2.2
+2.2.1
+2.2.1.1
+
+root
+2
+2.2
+2.2.1
+2.2.1.2
+
+root
+2
+2.3
+
+root
+2
+2.4
+</pre>
+</td></tr></table>
+
+Subcases can be nested to an arbitrary depth (limited only by your stack size). Each leaf subcase (a subcase that contains no nested subcases) will be executed exactly once on a separate path of execution from any other leaf subcase (so no leaf subcase can interfere with another). A fatal failure in a parent subcase will prevent nested subcases from running - but then that's the idea.
+
+You can check out how subcases are implemented in [**this example**](../../scripts/how_subcases_work/main.cpp#L1).
+
+## 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 **doctest** even quicker and easier. This is not really the best approach when you start writing more real-world tests.
+
+The requirement is that the following block of code ([**or equivalent**](main.md)):
+
+```c++
+#define DOCTEST_CONFIG_IMPLEMENT_WITH_MAIN
+#include "doctest.h"
+```
+
+appears in _exactly_ one translation unit (source file). Use as many additional source files as you need for your tests - partitioned however makes most sense for your way of working. Each additional file needs only to ```#include "doctest.h"``` - do not repeat the ```#define```!
+
+In fact it is usually a good idea to put the block with the ```#define``` in it's own source file.
+
+## Next steps
+
+This has been a brief introduction to get you up and running with **doctest** and to point out some of the key differences between **doctest** 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 - see the ever-growing [**reference**](readme.md#reference) section for what's available.
+
+---------------
+
+[Home](readme.md#reference)
diff --git a/doctest/doctest.h b/doctest/doctest.h
index 64d975e..d96c28e 100644
--- a/doctest/doctest.h
+++ b/doctest/doctest.h
@@ -1,2717 +1,2717 @@
-//
-// doctest.h - the lightest feature rich C++ single header testing framework
-//
-// Copyright (c) 2016 Viktor Kirilov
-//
-// Distributed under the MIT Software License
-// See accompanying file LICENSE.txt or copy at
-// https://opensource.org/licenses/MIT
-//
-// The documentation can be found at the library's page:
-// https://github.com/onqtam/doctest/blob/master/doc/markdown/readme.md
-//
-// The library is heavily influenced by Catch - https://github.com/philsquared/Catch
-// which uses the Boost Software License - Version 1.0
-// see here - https://github.com/philsquared/Catch/blob/master/LICENSE_1_0.txt
-// The concept of subcases (sections in Catch) and expression decomposition are from there.
-// Some parts of the code are taken directly:
-// - stringification - the detection of "ostream& operator<<(ostream&, const T&)" and the StringMaker class
-// - the Approx() helper class for floating point comparison
-// - colors in the console
-// - breaking into a debugger
-
-// =================================================================================================
-// =================================================================================================
-// =================================================================================================
-
-// Suppress this globally - there is no way to silence it in the expression decomposition macros
-// _Pragma() in macros doesn't work for the c++ front-end of g++
-// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=55578
-// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=69543
-// Also the warning is completely worthless nowadays - http://stackoverflow.com/questions/14016993
-#if defined(__GNUC__) && !defined(__clang__)
-#pragma GCC diagnostic ignored "-Waggregate-return"
-#endif
-
-#if defined(__clang__)
-#pragma clang diagnostic push
-#pragma clang diagnostic ignored "-Wpadded"
-#pragma clang diagnostic ignored "-Wglobal-constructors"
-#pragma clang diagnostic ignored "-Wexit-time-destructors"
-#pragma clang diagnostic ignored "-Wmissing-prototypes"
-#pragma clang diagnostic ignored "-Wsign-conversion"
-#pragma clang diagnostic ignored "-Wshorten-64-to-32"
-#pragma clang diagnostic ignored "-Wmissing-variable-declarations"
-#pragma clang diagnostic ignored "-Wcovered-switch-default"
-#pragma clang diagnostic ignored "-Wmissing-noreturn"
-#endif // __clang__
-
-#if defined(__GNUC__) && !defined(__clang__)
-#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ > 6)
-#pragma GCC diagnostic push
-#endif // > gcc 4.6
-#pragma GCC diagnostic ignored "-Wconversion"
-#pragma GCC diagnostic ignored "-Weffc++"
-#pragma GCC diagnostic ignored "-Wsign-conversion"
-#pragma GCC diagnostic ignored "-Wstrict-overflow"
-#pragma GCC diagnostic ignored "-Wmissing-declarations"
-#pragma GCC diagnostic ignored "-Winline"
-#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ > 6)
-#pragma GCC diagnostic ignored "-Wzero-as-null-pointer-constant"
-#endif // > gcc 4.6
-//#pragma GCC diagnostic ignored "-Wlong-long"
-#endif // __GNUC__
-
-#ifdef _MSC_VER
-#pragma warning(push)
-#pragma warning(disable : 4996) // The compiler encountered a deprecated declaration
-#pragma warning(disable : 4267) // 'var' : conversion from 'size_t' to 'type', possible loss of data
-#pragma warning(disable : 4706) // assignment within conditional expression
-#pragma warning(disable : 4512) // 'class' : assignment operator could not be generated
-#pragma warning(disable : 4127) // conditional expression is constant
-#endif // _MSC_VER
-
-#ifndef DOCTEST_LIBRARY_INCLUDED
-#define DOCTEST_LIBRARY_INCLUDED
-
-#define DOCTEST_VERSION_MAJOR 1
-#define DOCTEST_VERSION_MINOR 0
-#define DOCTEST_VERSION_PATCH 0
-#define DOCTEST_VERSION "1.0.0"
-
-// internal macros for string concatenation and anonymous variable name generation
-#define DOCTEST_CONCAT_IMPL(s1, s2) s1##s2
-#define DOCTEST_CONCAT(s1, s2) DOCTEST_CONCAT_IMPL(s1, s2)
-#ifdef __COUNTER__ // not standard and may be missing for some compilers
-#define DOCTEST_ANONYMOUS(x) DOCTEST_CONCAT(x, __COUNTER__)
-#else // __COUNTER__
-#define DOCTEST_ANONYMOUS(x) DOCTEST_CONCAT(x, __LINE__)
-#endif // __COUNTER__
-
-// internal macro for making a string
-#define DOCTEST_TOSTR_IMPL(x) #x
-#define DOCTEST_TOSTR(x) DOCTEST_TOSTR_IMPL(x)
-
-// internal macro for concatenating 2 literals and making the result a string
-#define DOCTEST_STR_CONCAT_TOSTR(s1, s2) DOCTEST_TOSTR(s1) DOCTEST_TOSTR(s2)
-
-// not using __APPLE__ because... this is how Catch does it
-#if defined(__MAC_OS_X_VERSION_MIN_REQUIRED)
-#define DOCTEST_PLATFORM_MAC
-#elif defined(__IPHONE_OS_VERSION_MIN_REQUIRED)
-#define DOCTEST_PLATFORM_IPHONE
-#elif defined(_WIN32) || defined(_MSC_VER)
-#define DOCTEST_PLATFORM_WINDOWS
-#else
-#define DOCTEST_PLATFORM_LINUX
-#endif
-
-#define DOCTEST_COUNTOF(x) (sizeof(x) / sizeof(x[0]))
-
-#define DOCTEST_GCS doctest::detail::getTestsContextState
-
-// snprintf() not in the C++98 standard
-#ifdef _MSC_VER
-#define DOCTEST_SNPRINTF _snprintf
-#else
-#define DOCTEST_SNPRINTF snprintf
-#endif
-
-// for anything below Visual Studio 2005 (VC++6 has no __debugbreak() - not sure about VS 2003)
-#if defined(_MSC_VER) && _MSC_VER < 1400
-#define __debugbreak() __asm { int 3}
-#endif
-
-#ifdef DOCTEST_PLATFORM_MAC
-// The following code snippet based on:
-// http://cocoawithlove.com/2008/03/break-into-debugger.html
-#ifdef DEBUG
-#if defined(__ppc64__) || defined(__ppc__)
-#define DOCTEST_BREAK_INTO_DEBUGGER() \
- if(doctest::detail::isDebuggerActive() && !DOCTEST_GCS()->no_breaks) \
- __asm__("li r0, 20\nsc\nnop\nli r0, 37\nli r4, 2\nsc\nnop\n" : : : "memory", "r0", "r3", "r4")
-#else // __ppc64__ || __ppc__
-#define DOCTEST_BREAK_INTO_DEBUGGER() \
- if(doctest::detail::isDebuggerActive() && !DOCTEST_GCS()->no_breaks) \
- __asm__("int $3\n" : :)
-#endif // __ppc64__ || __ppc__
-#endif // DEBUG
-#elif defined(_MSC_VER)
-#define DOCTEST_BREAK_INTO_DEBUGGER() \
- if(doctest::detail::isDebuggerActive() && !DOCTEST_GCS()->no_breaks) \
- __debugbreak()
-#elif defined(__MINGW32__)
-extern "C" __declspec(dllimport) void __stdcall DebugBreak();
-#define DOCTEST_BREAK_INTO_DEBUGGER() \
- if(doctest::detail::isDebuggerActive() && !DOCTEST_GCS()->no_breaks) \
- ::DebugBreak()
-#else // linux
-#define DOCTEST_BREAK_INTO_DEBUGGER() ((void)0)
-#endif // linux
-
-#ifdef __clang__
-#include <ciso646>
-#endif // __clang__
-
-#ifdef _LIBCPP_VERSION
-#include <iosfwd>
-#else // _LIBCPP_VERSION
-#ifndef DOCTEST_CONFIG_USE_IOSFWD
-namespace std
-{
-template <class charT>
-struct char_traits;
-template <>
-struct char_traits<char>;
-template <class charT, class traits>
-class basic_ostream;
-typedef basic_ostream<char, char_traits<char> > ostream;
-}
-#else // DOCTEST_CONFIG_USE_IOSFWD
-#include <iosfwd>
-#endif // DOCTEST_CONFIG_USE_IOSFWD
-#endif // _LIBCPP_VERSION
-
-#ifndef DOCTEST_CONFIG_WITH_LONG_LONG
-#if __cplusplus >= 201103L || (defined(_MSC_VER) && (_MSC_VER >= 1400))
-#define DOCTEST_CONFIG_WITH_LONG_LONG
-#endif // __cplusplus / _MSC_VER
-#endif // DOCTEST_CONFIG_WITH_LONG_LONG
-
-namespace doctest
-{
-class String
-{
- char* m_str;
-
- void copy(const String& other);
-
-public:
- String(const char* in = "");
- String(const String& other);
- ~String();
-
- String& operator=(const String& other);
-
- String operator+(const String& other) const;
- String& operator+=(const String& other);
-
- char& operator[](unsigned pos) { return m_str[pos]; }
- const char& operator[](unsigned pos) const { return m_str[pos]; }
-
- char* c_str() { return m_str; }
- const char* c_str() const { return m_str; }
-
- unsigned size() const;
- unsigned length() const;
-
- int compare(const char* other, bool no_case = false) const;
- int compare(const String& other, bool no_case = false) const;
-};
-
-// clang-format off
-inline bool operator==(const String& lhs, const String& rhs) { return lhs.compare(rhs) == 0; }
-inline bool operator!=(const String& lhs, const String& rhs) { return lhs.compare(rhs) != 0; }
-inline bool operator< (const String& lhs, const String& rhs) { return lhs.compare(rhs) < 0; }
-inline bool operator> (const String& lhs, const String& rhs) { return lhs.compare(rhs) > 0; }
-inline bool operator<=(const String& lhs, const String& rhs) { return (lhs != rhs) ? lhs.compare(rhs) < 0 : true; }
-inline bool operator>=(const String& lhs, const String& rhs) { return (lhs != rhs) ? lhs.compare(rhs) > 0 : true; }
-// clang-format on
-
-std::ostream& operator<<(std::ostream& stream, const String& in);
-
-namespace detail
-{
- template <bool>
- struct STATIC_ASSERT_No_output_stream_operator_found_for_type;
-
- template <>
- struct STATIC_ASSERT_No_output_stream_operator_found_for_type<true>
- {};
-
- namespace has_insertion_operator_impl
- {
- typedef char no;
- typedef char yes[2];
-
- template <bool in>
- void f() {
- STATIC_ASSERT_No_output_stream_operator_found_for_type<in>();
- }
-
- struct any_t
- {
- template <typename T>
- any_t(const T&) {
- f<false>();
- }
- };
-
- yes& testStreamable(std::ostream&);
- no testStreamable(no);
-
- no operator<<(const std::ostream&, const any_t&);
-
- template <typename T>
- struct has_insertion_operator
- {
- static std::ostream& s;
- static const T& t;
-// for anything below Visual Studio 2005 (VC++6 is troublesome - not sure about VS 2003)
-#if defined(_MSC_VER) && _MSC_VER < 1400
- enum
- {
- value
- };
-#else // _MSC_VER
- static const bool value = sizeof(testStreamable(s << t)) == sizeof(yes);
-#endif // _MSC_VER
- };
- } // namespace has_insertion_operator_impl
-
- template <typename T>
- struct has_insertion_operator : has_insertion_operator_impl::has_insertion_operator<T>
- {};
-
- std::ostream* createStream();
- String getStreamResult(std::ostream*);
- void freeStream(std::ostream*);
-
- template <bool C>
- struct StringMakerBase
- {
- template <typename T>
- static String convert(const T&) {
- return "{?}";
- }
- };
-
- template <>
- struct StringMakerBase<true>
- {
- template <typename T>
- static String convert(const T& in) {
- std::ostream* stream = createStream();
- *stream << in;
- String result = getStreamResult(stream);
- freeStream(stream);
- return result;
- }
- };
-
- String rawMemoryToString(const void* object, unsigned size);
-
- template <typename T>
- String rawMemoryToString(const T& object) {
- return rawMemoryToString(&object, sizeof(object));
- }
-} // namespace detail
-
-// for anything below Visual Studio 2005 (VC++6 is troublesome - not sure about VS 2003)
-#if defined(_MSC_VER) && _MSC_VER < 1400
-template <typename T>
-struct StringMaker : detail::StringMakerBase<false>
-{};
-#else // _MSC_VER
-template <typename T>
-struct StringMaker : detail::StringMakerBase<detail::has_insertion_operator<T>::value>
-{};
-#endif // _MSC_VER
-
-// not for anything below Visual Studio 2005 (VC++6 is troublesome - not sure about VS 2003)
-#if defined(_MSC_VER) && _MSC_VER >= 1400
-template <typename T>
-struct StringMaker<T*>
-{
- template <typename U>
- static String convert(U* p) {
- if(!p)
- return "NULL";
- else
- return detail::rawMemoryToString(p);
- }
-};
-
-template <typename R, typename C>
-struct StringMaker<R C::*>
-{
- static String convert(R C::*p) {
- if(!p)
- return "NULL";
- else
- return detail::rawMemoryToString(p);
- }
-};
-#endif // _MSC_VER
-
-template <typename T>
-String toString(const T& value) {
- return StringMaker<T>::convert(value);
-}
-
-String toString(const char* in);
-String toString(bool in);
-String toString(float in);
-String toString(double in);
-String toString(double long in);
-
-String toString(char in);
-String toString(char unsigned in);
-String toString(int short in);
-String toString(int short unsigned in);
-String toString(int in);
-String toString(int unsigned in);
-String toString(int long in);
-String toString(int long unsigned in);
-
-#ifdef DOCTEST_CONFIG_WITH_LONG_LONG
-String toString(int long long in);
-String toString(int long long unsigned in);
-#endif // DOCTEST_CONFIG_WITH_LONG_LONG
-
-class Approx
-{
-public:
- explicit Approx(double value);
-
- Approx(Approx const& other)
- : m_epsilon(other.m_epsilon)
- , m_scale(other.m_scale)
- , m_value(other.m_value) {}
-
- Approx operator()(double value) {
- Approx approx(value);
- approx.epsilon(m_epsilon);
- approx.scale(m_scale);
- return approx;
- }
-
- friend bool operator==(double lhs, Approx const& rhs);
- 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); }
-
- Approx& epsilon(double newEpsilon) {
- m_epsilon = newEpsilon;
- return *this;
- }
-
- Approx& scale(double newScale) {
- m_scale = newScale;
- return *this;
- }
-
- String toString() const;
-
-private:
- double m_epsilon;
- double m_scale;
- double m_value;
-};
-
-template <>
-inline String toString<Approx>(Approx const& value) {
- return value.toString();
-}
-
-#if !defined(DOCTEST_CONFIG_DISABLE)
-
-namespace detail
-{
- // the function type this library works with
- typedef void (*funcType)(void);
-
-// not for anything below Visual Studio 2005 (VC++6 has no SFINAE - not sure about VS 2003)
-#if !defined(_MSC_VER) || _MSC_VER >= 1400
- // clang-format off
- template<class T> struct decay_array { typedef T type; };
- template<class T, unsigned N> struct decay_array<T[N]> { typedef T* type; };
- template<class T> struct decay_array<T[]> { typedef T* type; };
-
- template<class T> struct not_char_pointer { enum { value = true }; };
- template<> struct not_char_pointer<char*> { enum { value = false }; };
- template<> struct not_char_pointer<const char*> { enum { value = false }; };
-
- template<class T> struct can_use_op : not_char_pointer<typename decay_array<T>::type> {};
-
- template<bool, class = void> struct enable_if {};
- template<class T> struct enable_if<true, T> { typedef T type; };
-// clang-format on
-#endif // _MSC_VER
-
- struct TestFailureException
- {};
-
- void checkIfShouldThrow(const char* assert_name);
- void throwException();
- bool always_false();
- void* getNullPtr();
-
- // a struct defining a registered test callback
- struct TestData
- {
- // not used for determining uniqueness
- const char* m_suite; // the test suite in which the test was added
- const char* m_name; // name of the test function
- funcType m_f; // a function pointer to the test function
-
- // fields by which uniqueness of test cases shall be determined
- const char* m_file; // the file in which the test was registered
- unsigned m_line; // the line where the test was registered
-
- TestData(const char* suite, const char* name, funcType f, const char* file, int line)
- : m_suite(suite)
- , m_name(name)
- , m_f(f)
- , m_file(file)
- , m_line(line) {}
-
- bool operator==(const TestData& other) const;
- };
-
- struct Subcase
- {
- const char* m_name;
- const char* m_file;
- int m_line;
- bool m_entered;
-
- Subcase(const char* name, const char* file, int line);
- ~Subcase();
- Subcase(const Subcase& other);
- Subcase& operator=(const Subcase& other);
-
- bool operator==(const Subcase& other) const;
- operator bool() const { return m_entered; }
- };
-
- template <typename L, typename R>
- String stringifyBinaryExpr(const L& lhs, const char* op, const R& rhs) {
- return toString(lhs) + " " + op + " " + toString(rhs);
- }
-
- // TODO: think about this
- //struct STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison;
-
- struct Result
- {
- bool m_passed;
- String m_decomposition;
-
-// to fix gcc 4.7 "-Winline" warnings
-#if defined(__GNUC__) && !defined(__clang__)
- __attribute__((noinline))
-#endif
- ~Result() {
- }
-
- Result(bool passed = false, const String& decomposition = String())
- : m_passed(passed)
- , m_decomposition(decomposition) {}
-
-// to fix gcc 4.7 "-Winline" warnings
-#if defined(__GNUC__) && !defined(__clang__)
- __attribute__((noinline))
-#endif
- Result&
- operator=(const Result& other) {
- m_passed = other.m_passed;
- m_decomposition = other.m_decomposition;
-
- return *this;
- }
-
- operator bool() { return !m_passed; }
-
- void invert() { m_passed = !m_passed; }
-
- // clang-format off
- //template <typename R> STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator+(const R&);
- //template <typename R> STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator-(const R&);
- //template <typename R> STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator/(const R&);
- //template <typename R> STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator*(const R&);
- //template <typename R> STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator&&(const R&);
- //template <typename R> STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator||(const R&);
- //
- //template <typename R> STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator==(const R&);
- //template <typename R> STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator!=(const R&);
- //template <typename R> STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator<(const R&);
- //template <typename R> STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator<=(const R&);
- //template <typename R> STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator>(const R&);
- //template <typename R> STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator>=(const R&);
- // clang-format on
- };
-
-// clang-format off
-
-// for anything below Visual Studio 2005 (VC++6 has no SFINAE - not sure about VS 2003)
-#if defined(_MSC_VER) && _MSC_VER < 1400
- template <typename L, typename R> bool eq (const L& lhs, const R& rhs) { return lhs == rhs; }
- template <typename L, typename R> bool neq(const L& lhs, const R& rhs) { return lhs != rhs; }
- template <typename L, typename R> bool lt (const L& lhs, const R& rhs) { return lhs < rhs; }
- template <typename L, typename R> bool gt (const L& lhs, const R& rhs) { return lhs > rhs; }
- template <typename L, typename R> bool lte(const L& lhs, const R& rhs) { return eq(lhs, rhs) != 0 ? lhs < rhs : true; }
- template <typename L, typename R> bool gte(const L& lhs, const R& rhs) { return eq(lhs, rhs) != 0 ? lhs > rhs : true; }
-#else // _MSC_VER
- template <typename L, typename R>
- typename enable_if<can_use_op<L>::value || can_use_op<R>::value, bool>::type eq (const L& lhs, const R& rhs) { return lhs == rhs; }
- template <typename L, typename R>
- typename enable_if<can_use_op<L>::value || can_use_op<R>::value, bool>::type neq(const L& lhs, const R& rhs) { return lhs != rhs; }
- template <typename L, typename R>
- typename enable_if<can_use_op<L>::value || can_use_op<R>::value, bool>::type lt (const L& lhs, const R& rhs) { return lhs < rhs; }
- template <typename L, typename R>
- typename enable_if<can_use_op<L>::value || can_use_op<R>::value, bool>::type gt (const L& lhs, const R& rhs) { return lhs > rhs; }
- template <typename L, typename R>
- typename enable_if<can_use_op<L>::value || can_use_op<R>::value, bool>::type lte(const L& lhs, const R& rhs) { return neq(lhs, rhs) ? lhs < rhs : true; }
- template <typename L, typename R>
- typename enable_if<can_use_op<L>::value || can_use_op<R>::value, bool>::type gte(const L& lhs, const R& rhs) { return neq(lhs, rhs) ? lhs > rhs : true; }
-
- inline bool eq (const char* lhs, const char* rhs) { return String(lhs) == String(rhs); }
- inline bool neq(const char* lhs, const char* rhs) { return String(lhs) != String(rhs); }
- inline bool lt (const char* lhs, const char* rhs) { return String(lhs) < String(rhs); }
- inline bool gt (const char* lhs, const char* rhs) { return String(lhs) > String(rhs); }
- inline bool lte(const char* lhs, const char* rhs) { return String(lhs) <= String(rhs); }
- inline bool gte(const char* lhs, const char* rhs) { return String(lhs) >= String(rhs); }
-#endif // _MSC_VER
-
- // clang-format on
-
- template <typename L>
- struct Expression_lhs
- {
- L lhs;
-
- Expression_lhs(L in)
- : lhs(in) {}
-
- Expression_lhs(const Expression_lhs& other)
- : lhs(other.lhs) {}
-
- operator Result() { return Result(!!lhs, toString(lhs)); }
-
- // clang-format off
- template <typename R> Result operator==(const R& rhs) { return Result(eq (lhs, rhs), stringifyBinaryExpr(lhs, "==", rhs)); }
- template <typename R> Result operator!=(const R& rhs) { return Result(neq(lhs, rhs), stringifyBinaryExpr(lhs, "!=", rhs)); }
- template <typename R> Result operator< (const R& rhs) { return Result(lt (lhs, rhs), stringifyBinaryExpr(lhs, "<" , rhs)); }
- template <typename R> Result operator<=(const R& rhs) { return Result(lte(lhs, rhs), stringifyBinaryExpr(lhs, "<=", rhs)); }
- template <typename R> Result operator> (const R& rhs) { return Result(gt (lhs, rhs), stringifyBinaryExpr(lhs, ">" , rhs)); }
- template <typename R> Result operator>=(const R& rhs) { return Result(gte(lhs, rhs), stringifyBinaryExpr(lhs, ">=", rhs)); }
- // clang-format on
- };
-
- struct ExpressionDecomposer
- {
- template <typename L>
- Expression_lhs<const L&> operator<<(const L& operand) {
- return Expression_lhs<const L&>(operand);
- }
- };
-
- // forward declarations of functions used by the macros
- int regTest(void (*f)(void), unsigned line, const char* file, const char* name);
- int setTestSuiteName(const char* name);
-
- void addFailedAssert(const char* assert_name);
-
- void logTestStart(const char* name, const char* file, unsigned line);
- void logTestEnd();
-
- void logTestCrashed();
-
- void logAssert(bool passed, const char* decomposition, bool threw, const char* expr,
- const char* assert_name, const char* file, int line);
-
- void logAssertThrows(bool threw, const char* expr, const char* assert_name, const char* file,
- int line);
-
- void logAssertThrowsAs(bool threw, bool threw_as, const char* as, const char* expr,
- const char* assert_name, const char* file, int line);
-
- void logAssertNothrow(bool threw, const char* expr, const char* assert_name, const char* file,
- int line);
-
- bool isDebuggerActive();
- void writeToDebugConsole(const String&);
-
- struct TestAccessibleContextState
- {
- bool success; // include successful assertions in output
- bool no_throw; // to skip exceptions-related assertion macros
- bool no_breaks; // to not break into the debugger
- const TestData* currentTest;
- bool hasLoggedCurrentTestStart;
- int numAssertionsForCurrentTestcase;
- };
-
- struct ContextState;
-
- TestAccessibleContextState* getTestsContextState();
-} // namespace detail
-
-#endif // DOCTEST_CONFIG_DISABLE
-
-class Context
-{
-#if !defined(DOCTEST_CONFIG_DISABLE)
- detail::ContextState* p;
-
- void parseArgs(int argc, const char* const* argv, bool withDefaults = false);
-
-#endif // DOCTEST_CONFIG_DISABLE
-
-public:
- Context(int argc, const char* const* argv);
-
-// to fix gcc 4.7 "-Winline" warnings
-#if defined(__GNUC__) && !defined(__clang__)
- __attribute__((noinline))
-#endif
- ~Context();
-
- void addFilter(const char* filter, const char* value);
- void setOption(const char* option, int value);
- void setOption(const char* option, const char* value);
-
- bool shouldExit();
-
- int run();
-};
-
-} // namespace doctest
-
-// if registering is not disabled
-#if !defined(DOCTEST_CONFIG_DISABLE)
-
-// registers the test by initializing a dummy var with a function
-#if defined(__GNUC__) && !defined(__clang__)
-#define DOCTEST_REGISTER_FUNCTION(f, name) \
- static int DOCTEST_ANONYMOUS(DOCTEST_AUTOGEN_VAR_) __attribute__((unused)) = \
- doctest::detail::regTest(f, __LINE__, __FILE__, name);
-#elif defined(__clang__)
-#define DOCTEST_REGISTER_FUNCTION(f, name) \
- _Pragma("clang diagnostic push") \
- _Pragma("clang diagnostic ignored \"-Wglobal-constructors\"") static int \
- DOCTEST_ANONYMOUS(DOCTEST_AUTOGEN_VAR_) = \
- doctest::detail::regTest(f, __LINE__, __FILE__, name); \
- _Pragma("clang diagnostic pop")
-#else // MSVC
-#define DOCTEST_REGISTER_FUNCTION(f, name) \
- static int DOCTEST_ANONYMOUS(DOCTEST_AUTOGEN_VAR_) = \
- doctest::detail::regTest(f, __LINE__, __FILE__, name);
-#endif // MSVC
-
-#define DOCTEST_IMPLEMENT_FIXTURE(der, base, func, name) \
- namespace \
- { \
- struct der : base \
- { void f(); }; \
- static void func() { \
- der v; \
- v.f(); \
- } \
- DOCTEST_REGISTER_FUNCTION(func, name) \
- } \
- inline void der::f()
-
-#define DOCTEST_CREATE_AND_REGISTER_FUNCTION(f, name) \
- static void f(); \
- DOCTEST_REGISTER_FUNCTION(f, name) \
- inline void f()
-
-// for registering tests
-#define DOCTEST_TEST_CASE(name) \
- DOCTEST_CREATE_AND_REGISTER_FUNCTION(DOCTEST_ANONYMOUS(DOCTEST_AUTOGEN_FUNC_), name)
-
-// for registering tests with a fixture
-#define DOCTEST_TEST_CASE_FIXTURE(c, name) \
- DOCTEST_IMPLEMENT_FIXTURE(DOCTEST_ANONYMOUS(DOCTEST_AUTOGEN_CLASS_), c, \
- DOCTEST_ANONYMOUS(DOCTEST_AUTOGEN_FUNC_), name)
-
-// for subcases
-#if defined(__GNUC__)
-#define DOCTEST_SUBCASE(name) \
- if(const doctest::detail::Subcase & DOCTEST_ANONYMOUS(DOCTEST_AUTOGEN_SUBCASE_) \
- __attribute__((unused)) = \
- doctest::detail::Subcase(name, __FILE__, __LINE__))
-#else // __GNUC__
-#define DOCTEST_SUBCASE(name) \
- if(const doctest::detail::Subcase & DOCTEST_ANONYMOUS(DOCTEST_AUTOGEN_SUBCASE_) = \
- doctest::detail::Subcase(name, __FILE__, __LINE__))
-#endif // __GNUC__
-
-// for starting a testsuite block
-#if defined(__GNUC__) && !defined(__clang__)
-#define DOCTEST_TEST_SUITE(name) \
- static int DOCTEST_ANONYMOUS(DOCTEST_AUTOGEN_VAR_) __attribute__((unused)) = \
- doctest::detail::setTestSuiteName(name); \
- void DOCTEST_ANONYMOUS(DOCTEST_AUTOGEN_FOR_SEMICOLON_)()
-#elif defined(__clang__)
-#define DOCTEST_TEST_SUITE(name) \
- _Pragma("clang diagnostic push") \
- _Pragma("clang diagnostic ignored \"-Wglobal-constructors\"") static int \
- DOCTEST_ANONYMOUS(DOCTEST_AUTOGEN_VAR_) = \
- doctest::detail::setTestSuiteName(name); \
- _Pragma("clang diagnostic pop") void DOCTEST_ANONYMOUS(DOCTEST_AUTOGEN_FOR_SEMICOLON_)()
-#else // MSVC
-#define DOCTEST_TEST_SUITE(name) \
- static int DOCTEST_ANONYMOUS(DOCTEST_AUTOGEN_VAR_) = doctest::detail::setTestSuiteName(name); \
- void DOCTEST_ANONYMOUS(DOCTEST_AUTOGEN_FOR_SEMICOLON_)()
-#endif // MSVC
-
-// for ending a testsuite block
-#if defined(__GNUC__) && !defined(__clang__)
-#define DOCTEST_TEST_SUITE_END \
- static int DOCTEST_ANONYMOUS(DOCTEST_AUTOGEN_VAR_) __attribute__((unused)) = \
- doctest::detail::setTestSuiteName(""); \
- void DOCTEST_ANONYMOUS(DOCTEST_AUTOGEN_TESTSUITE_END_)
-#elif defined(__clang__)
-#define DOCTEST_TEST_SUITE_END \
- _Pragma("clang diagnostic push") \
- _Pragma("clang diagnostic ignored \"-Wglobal-constructors\"") static int \
- DOCTEST_ANONYMOUS(DOCTEST_AUTOGEN_VAR_) = \
- doctest::detail::setTestSuiteName(""); \
- _Pragma("clang diagnostic pop") void DOCTEST_ANONYMOUS(DOCTEST_AUTOGEN_TESTSUITE_END_)
-#else // MSVC
-#define DOCTEST_TEST_SUITE_END \
- static int DOCTEST_ANONYMOUS(DOCTEST_AUTOGEN_VAR_) = doctest::detail::setTestSuiteName(""); \
- void DOCTEST_ANONYMOUS(DOCTEST_AUTOGEN_TESTSUITE_END_)
-#endif // MSVC
-
-#define DOCTEST_LOG_START() \
- do { \
- if(!DOCTEST_GCS()->hasLoggedCurrentTestStart) { \
- doctest::detail::logTestStart(DOCTEST_GCS()->currentTest->m_name, \
- DOCTEST_GCS()->currentTest->m_file, \
- DOCTEST_GCS()->currentTest->m_line); \
- DOCTEST_GCS()->hasLoggedCurrentTestStart = true; \
- } \
- } while(doctest::detail::always_false())
-
-#define DOCTEST_ASSERT_IMPLEMENT(expr, assert_name, false_invert_op) \
- doctest::detail::Result res; \
- bool threw = false; \
- try { \
- res = doctest::detail::ExpressionDecomposer() << expr; \
- } catch(...) { threw = true; } \
- false_invert_op; \
- if(res || DOCTEST_GCS()->success) { \
- DOCTEST_LOG_START(); \
- doctest::detail::logAssert(res.m_passed, res.m_decomposition.c_str(), threw, #expr, \
- assert_name, __FILE__, __LINE__); \
- } \
- DOCTEST_GCS()->numAssertionsForCurrentTestcase++; \
- if(res) { \
- doctest::detail::addFailedAssert(assert_name); \
- DOCTEST_BREAK_INTO_DEBUGGER(); \
- doctest::detail::checkIfShouldThrow(assert_name); \
- }
-
-#if defined(__clang__)
-#define DOCTEST_ASSERT_PROXY(expr, assert_name, false_invert_op) \
- do { \
- _Pragma("clang diagnostic push") \
- _Pragma("clang diagnostic ignored \"-Woverloaded-shift-op-parentheses\"") \
- DOCTEST_ASSERT_IMPLEMENT(expr, assert_name, false_invert_op) \
- _Pragma("clang diagnostic pop") \
- } while(doctest::detail::always_false())
-#else // __clang__
-#define DOCTEST_ASSERT_PROXY(expr, assert_name, false_invert_op) \
- do { \
- DOCTEST_ASSERT_IMPLEMENT(expr, assert_name, false_invert_op) \
- } while(doctest::detail::always_false())
-#endif // __clang__
-
-#define DOCTEST_WARN(expr) DOCTEST_ASSERT_PROXY(expr, "WARN", ((void)0))
-#define DOCTEST_CHECK(expr) DOCTEST_ASSERT_PROXY(expr, "CHECK", ((void)0))
-#define DOCTEST_REQUIRE(expr) DOCTEST_ASSERT_PROXY(expr, "REQUIRE", ((void)0))
-
-#define DOCTEST_WARN_FALSE(expr) DOCTEST_ASSERT_PROXY(expr, "WARN_FALSE", res.invert())
-#define DOCTEST_CHECK_FALSE(expr) DOCTEST_ASSERT_PROXY(expr, "CHECK_FALSE", res.invert())
-#define DOCTEST_REQUIRE_FALSE(expr) DOCTEST_ASSERT_PROXY(expr, "REQUIRE_FALSE", res.invert())
-
-#define DOCTEST_ASSERT_THROWS(expr, assert_name) \
- do { \
- if(!DOCTEST_GCS()->no_throw) { \
- bool threw = false; \
- try { \
- expr; \
- } catch(...) { threw = true; } \
- if(!threw || DOCTEST_GCS()->success) { \
- DOCTEST_LOG_START(); \
- doctest::detail::logAssertThrows(threw, #expr, assert_name, __FILE__, __LINE__); \
- } \
- DOCTEST_GCS()->numAssertionsForCurrentTestcase++; \
- if(!threw) { \
- doctest::detail::addFailedAssert(assert_name); \
- DOCTEST_BREAK_INTO_DEBUGGER(); \
- doctest::detail::checkIfShouldThrow(assert_name); \
- } \
- } \
- } while(doctest::detail::always_false())
-
-#define DOCTEST_ASSERT_THROWS_AS(expr, as, assert_name) \
- do { \
- if(!DOCTEST_GCS()->no_throw) { \
- bool threw = false; \
- bool threw_as = false; \
- try { \
- expr; \
- } catch(as) { \
- threw = true; \
- threw_as = true; \
- } catch(...) { threw = true; } \
- if(!threw_as || DOCTEST_GCS()->success) { \
- DOCTEST_LOG_START(); \
- doctest::detail::logAssertThrowsAs(threw, threw_as, #as, #expr, assert_name, \
- __FILE__, __LINE__); \
- } \
- DOCTEST_GCS()->numAssertionsForCurrentTestcase++; \
- if(!threw_as) { \
- doctest::detail::addFailedAssert(assert_name); \
- DOCTEST_BREAK_INTO_DEBUGGER(); \
- doctest::detail::checkIfShouldThrow(assert_name); \
- } \
- } \
- } while(doctest::detail::always_false())
-
-#define DOCTEST_ASSERT_NOTHROW(expr, assert_name) \
- do { \
- if(!DOCTEST_GCS()->no_throw) { \
- bool threw = false; \
- try { \
- expr; \
- } catch(...) { threw = true; } \
- if(threw || DOCTEST_GCS()->success) { \
- DOCTEST_LOG_START(); \
- doctest::detail::logAssertNothrow(threw, #expr, assert_name, __FILE__, __LINE__); \
- } \
- DOCTEST_GCS()->numAssertionsForCurrentTestcase++; \
- if(threw) { \
- doctest::detail::addFailedAssert(assert_name); \
- DOCTEST_BREAK_INTO_DEBUGGER(); \
- doctest::detail::checkIfShouldThrow(assert_name); \
- } \
- } \
- } while(doctest::detail::always_false())
-
-#define DOCTEST_WARN_THROWS(expr) DOCTEST_ASSERT_THROWS(expr, "WARN_THROWS")
-#define DOCTEST_CHECK_THROWS(expr) DOCTEST_ASSERT_THROWS(expr, "CHECK_THROWS")
-#define DOCTEST_REQUIRE_THROWS(expr) DOCTEST_ASSERT_THROWS(expr, "REQUIRE_THROWS")
-
-#define DOCTEST_WARN_THROWS_AS(expr, ex) DOCTEST_ASSERT_THROWS_AS(expr, ex, "WARN_THROWS_AS")
-#define DOCTEST_CHECK_THROWS_AS(expr, ex) DOCTEST_ASSERT_THROWS_AS(expr, ex, "CHECK_THROWS_AS")
-#define DOCTEST_REQUIRE_THROWS_AS(expr, ex) DOCTEST_ASSERT_THROWS_AS(expr, ex, "REQUIRE_THROWS_AS")
-
-#define DOCTEST_WARN_NOTHROW(expr) DOCTEST_ASSERT_NOTHROW(expr, "WARN_NOTHROW")
-#define DOCTEST_CHECK_NOTHROW(expr) DOCTEST_ASSERT_NOTHROW(expr, "CHECK_NOTHROW")
-#define DOCTEST_REQUIRE_NOTHROW(expr) DOCTEST_ASSERT_NOTHROW(expr, "REQUIRE_NOTHROW")
-
-// =================================================================================================
-// == WHAT FOLLOWS IS VERSIONS OF THE MACROS THAT DO NOT DO ANY REGISTERING! ==
-// == THIS CAN BE ENABLED BY DEFINING DOCTEST_CONFIG_DISABLE GLOBALLY! ==
-// =================================================================================================
-#else // DOCTEST_CONFIG_DISABLE
-
-#define DOCTEST_IMPLEMENT_FIXTURE(der, base, func, name) \
- namespace \
- { \
- template <typename T> \
- struct der : base \
- { void f(); }; \
- } \
- template <typename T> \
- inline void der<T>::f()
-
-#define DOCTEST_CREATE_AND_REGISTER_FUNCTION(f, name) \
- template <typename T> \
- static inline void f()
-
-// for registering tests
-#define DOCTEST_TEST_CASE(name) \
- DOCTEST_CREATE_AND_REGISTER_FUNCTION(DOCTEST_ANONYMOUS(DOCTEST_AUTOGEN_FUNC_), name)
-
-// for registering tests with a fixture
-#define DOCTEST_TEST_CASE_FIXTURE(x, name) \
- DOCTEST_IMPLEMENT_FIXTURE(DOCTEST_ANONYMOUS(DOCTEST_AUTOGEN_CLASS_), x, \
- DOCTEST_ANONYMOUS(DOCTEST_AUTOGEN_FUNC_), name)
-
-// for subcases
-#define DOCTEST_SUBCASE(name)
-
-// for starting a testsuite block
-#define DOCTEST_TEST_SUITE(name) void DOCTEST_ANONYMOUS(DOCTEST_AUTOGEN_FOR_SEMICOLON_)()
-
-// for ending a testsuite block
-#define DOCTEST_TEST_SUITE_END void DOCTEST_ANONYMOUS(DOCTEST_AUTOGEN_TESTSUITE_END_)
-
-#define DOCTEST_WARN(expr) ((void)0)
-#define DOCTEST_WARN_FALSE(expr) ((void)0)
-#define DOCTEST_WARN_THROWS(expr) ((void)0)
-#define DOCTEST_WARN_THROWS_AS(expr, ex) ((void)0)
-#define DOCTEST_WARN_NOTHROW(expr) ((void)0)
-#define DOCTEST_CHECK(expr) ((void)0)
-#define DOCTEST_CHECK_FALSE(expr) ((void)0)
-#define DOCTEST_CHECK_THROWS(expr) ((void)0)
-#define DOCTEST_CHECK_THROWS_AS(expr, ex) ((void)0)
-#define DOCTEST_CHECK_NOTHROW(expr) ((void)0)
-#define DOCTEST_REQUIRE(expr) ((void)0)
-#define DOCTEST_REQUIRE_FALSE(expr) ((void)0)
-#define DOCTEST_REQUIRE_THROWS(expr) ((void)0)
-#define DOCTEST_REQUIRE_THROWS_AS(expr, ex) ((void)0)
-#define DOCTEST_REQUIRE_NOTHROW(expr) ((void)0)
-
-#endif // DOCTEST_CONFIG_DISABLE
-
-// BDD style macros
-#define DOCTEST_SCENARIO(name) TEST_CASE("Scenario: " name)
-#define DOCTEST_GIVEN(name) SUBCASE(" Given: " name)
-#define DOCTEST_WHEN(name) SUBCASE(" When: " name)
-#define DOCTEST_AND_WHEN(name) SUBCASE("And when: " name)
-#define DOCTEST_THEN(name) SUBCASE(" Then: " name)
-#define DOCTEST_AND_THEN(name) SUBCASE(" And: " name)
-
-// == SHORT VERSIONS OF THE MACROS
-#if !defined(DOCTEST_CONFIG_NO_SHORT_MACRO_NAMES)
-
-#define TEST_CASE DOCTEST_TEST_CASE
-#define TEST_CASE_FIXTURE DOCTEST_TEST_CASE_FIXTURE
-#define SUBCASE DOCTEST_SUBCASE
-#define TEST_SUITE DOCTEST_TEST_SUITE
-#define TEST_SUITE_END DOCTEST_TEST_SUITE_END
-#define WARN DOCTEST_WARN
-#define WARN_FALSE DOCTEST_WARN_FALSE
-#define WARN_THROWS DOCTEST_WARN_THROWS
-#define WARN_THROWS_AS DOCTEST_WARN_THROWS_AS
-#define WARN_NOTHROW DOCTEST_WARN_NOTHROW
-#define CHECK DOCTEST_CHECK
-#define CHECK_FALSE DOCTEST_CHECK_FALSE
-#define CHECK_THROWS DOCTEST_CHECK_THROWS
-#define CHECK_THROWS_AS DOCTEST_CHECK_THROWS_AS
-#define CHECK_NOTHROW DOCTEST_CHECK_NOTHROW
-#define REQUIRE DOCTEST_REQUIRE
-#define REQUIRE_FALSE DOCTEST_REQUIRE_FALSE
-#define REQUIRE_THROWS DOCTEST_REQUIRE_THROWS
-#define REQUIRE_THROWS_AS DOCTEST_REQUIRE_THROWS_AS
-#define REQUIRE_NOTHROW DOCTEST_REQUIRE_NOTHROW
-
-#define SCENARIO DOCTEST_SCENARIO
-#define GIVEN DOCTEST_GIVEN
-#define WHEN DOCTEST_WHEN
-#define AND_WHEN DOCTEST_AND_WHEN
-#define THEN DOCTEST_THEN
-#define AND_THEN DOCTEST_AND_THEN
-
-#endif // DOCTEST_CONFIG_NO_SHORT_MACRO_NAMES
-
-// this is here to clear the 'current test suite' for the current translation unit - at the top
-DOCTEST_TEST_SUITE_END();
-
-#endif // DOCTEST_LIBRARY_INCLUDED
-
-// =================================================================================================
-// == WHAT FOLLOWS IS THE IMPLEMENTATION OF THE TEST RUNNER ==
-// =================================================================================================
-#if(defined(DOCTEST_CONFIG_IMPLEMENT) || defined(DOCTEST_CONFIG_IMPLEMENT_WITH_MAIN))
-#ifndef DOCTEST_LIBRARY_IMPLEMENTATION
-#define DOCTEST_LIBRARY_IMPLEMENTATION
-
-// required includes - will go only in one translation unit!
-#include <ctime>
-#include <cmath>
-#include <new>
-#include <cstdio>
-#include <cstdlib>
-#include <cstring>
-#include <limits>
-#include <sstream>
-#include <iomanip>
-
-namespace doctest
-{
-namespace detail
-{
- // not using std::strlen() because of valgrind errors when optimizations are turned on
- // 'Invalid read of size 4' when the test suite len (with '\0') is not a multiple of 4
- // for details see http://stackoverflow.com/questions/35671155
- size_t my_strlen(const char* in) {
- const char* temp = in;
- while(*temp)
- ++temp;
- return temp - in;
- }
-
- template <typename T>
- T my_max(const T& lhs, const T& rhs) {
- return lhs > rhs ? lhs : rhs;
- }
-
- // case insensitive strcmp
- int stricmp(char const* a, char const* b) {
- for(;; a++, b++) {
- int d = tolower(*a) - tolower(*b);
- if(d != 0 || !*a)
- return d;
- }
- }
-
- template <typename T>
- String fpToString(T value, int precision) {
- std::ostringstream oss;
- oss << std::setprecision(precision) << std::fixed << value;
- std::string d = oss.str();
- 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.c_str();
- }
-
- 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;
- }
- };
-
- String rawMemoryToString(const void* object, unsigned size) {
- // Reverse order for little endian architectures
- int i = 0, end = static_cast<int>(size), inc = 1;
- if(Endianness::which() == Endianness::Little) {
- i = end - 1;
- end = inc = -1;
- }
-
- unsigned char const* bytes = static_cast<unsigned char const*>(object);
- std::ostringstream os;
- os << "0x" << std::setfill('0') << std::hex;
- for(; i != end; i += inc)
- os << std::setw(2) << static_cast<unsigned>(bytes[i]);
- return os.str().c_str();
- }
-
- std::ostream* createStream() { return new std::ostringstream(); }
- String getStreamResult(std::ostream* in) {
- return static_cast<std::ostringstream*>(in)->str().c_str();
- }
- void freeStream(std::ostream* in) { delete in; }
-
-#ifndef DOCTEST_CONFIG_DISABLE
- template <class T>
- class Vector
- {
- unsigned m_size;
- unsigned m_capacity;
- T* m_buffer;
-
- public:
- Vector();
- Vector(unsigned num, const T& val = T());
- Vector(const Vector& other);
- ~Vector();
- Vector& operator=(const Vector& other);
-
- T* data() { return m_buffer; }
- const T* data() const { return m_buffer; }
- unsigned size() const { return m_size; }
-
- T& operator[](unsigned index) { return m_buffer[index]; }
- const T& operator[](unsigned index) const { return m_buffer[index]; }
-
- void clear();
- void pop_back();
- void push_back(const T& item);
- void resize(unsigned num, const T& val = T());
- };
-
- // the default Hash() implementation that the HashTable class uses - returns 0 - very naive
- // specialize for better HashTable performance
- template <typename T>
- unsigned Hash(const T&) {
- return 0;
- }
-
- template <class T>
- class HashTable
- {
- Vector<Vector<T> > buckets;
-
- public:
- explicit HashTable(unsigned num_buckets)
- : buckets(num_buckets) {}
-
- bool has(const T& in) const {
- const Vector<T>& bucket = buckets[Hash(in) % buckets.size()];
- for(unsigned i = 0; i < bucket.size(); ++i)
- if(bucket[i] == in)
- return true;
- return false;
- }
-
- void insert(const T& in) {
- if(!has(in))
- buckets[Hash(in) % buckets.size()].push_back(in);
- }
-
- void clear() {
- for(unsigned i = 0; i < buckets.size(); ++i)
- buckets[i].clear();
- }
-
- const Vector<Vector<T> >& getBuckets() const { return buckets; }
- };
-
- // this holds both parameters for the command line and runtime data for tests
- struct ContextState : TestAccessibleContextState
- {
- // == parameters from the command line
-
- detail::Vector<detail::Vector<String> > filters;
-
- String order_by; // how tests should be ordered
- unsigned rand_seed; // the seed for rand ordering
-
- unsigned first; // the first (matching) test to be executed
- unsigned last; // the last (matching) test to be executed
-
- int abort_after; // stop tests after this many failed assertions
- bool case_sensitive; // if filtering should be case sensitive
- bool exit; // if the program should be exited after the tests are ran/whatever
- bool no_overrides; // to disable overrides from code
- bool no_exitcode; // if the framework should return 0 as the exitcode
- bool no_run; // to not run the tests at all (can be done with an "*" exclude)
- bool no_colors; // if output to the console should be colorized
- bool no_path_in_filenames; // if the path to files should be removed from the output
-
- bool help; // to print the help
- bool version; // to print the version
- bool count; // if only the count of matching tests is to be retreived
- bool list_test_cases; // to list all tests matching the filters
- bool list_test_suites; // to list all suites matching the filters
- bool hash_table_histogram; // if the hash table should be printed as a histogram
-
- // == data for the tests being ran
-
- int numAssertions;
- int numFailedAssertions;
- int numFailedAssertionsForCurrentTestcase;
-
- // stuff for subcases
- HashTable<Subcase> subcasesPassed;
- HashTable<int> subcasesEnteredLevels;
- Vector<Subcase> subcasesStack;
- int subcasesCurrentLevel;
- bool subcasesHasSkipped;
-
- void resetRunData() {
- numAssertions = 0;
- numFailedAssertions = 0;
- }
-
- ContextState()
- : filters(6) // 6 different filters total
- , subcasesPassed(100)
- , subcasesEnteredLevels(100) {
- resetRunData();
- }
- };
-
- ContextState*& getContextState();
-#endif
-} // namespace detail
-
-String::String(const char* in) {
- m_str = static_cast<char*>(malloc(detail::my_strlen(in) + 1));
- strcpy(m_str, in);
-}
-
-String::String(const String& other)
- : m_str(0) {
- copy(other);
-}
-
-void String::copy(const String& other) {
- if(m_str)
- free(m_str);
- m_str = 0;
-
- if(other.m_str) {
- m_str = static_cast<char*>(malloc(detail::my_strlen(other.m_str) + 1));
- strcpy(m_str, other.m_str);
- }
-}
-
-String::~String() {
- if(m_str)
- free(m_str);
-}
-
-String& String::operator=(const String& other) {
- if(this != &other)
- copy(other);
- return *this;
-}
-
-String String::operator+(const String& other) const { return String(m_str) += other; }
-
-String& String::operator+=(const String& other) {
- using namespace detail;
- if(m_str == 0) {
- copy(other);
- } else if(other.m_str != 0) {
- char* newStr = static_cast<char*>(malloc(my_strlen(m_str) + my_strlen(other.m_str) + 1));
- strcpy(newStr, m_str);
- strcpy(newStr + my_strlen(m_str), other.m_str);
- free(m_str);
- m_str = newStr;
- }
- return *this;
-}
-
-unsigned String::size() const { return m_str ? detail::my_strlen(m_str) : 0; }
-unsigned String::length() const { return size(); }
-
-int String::compare(const char* other, bool no_case) const {
- if(no_case)
- return detail::stricmp(m_str, other);
- return strcmp(m_str, other);
-}
-
-int String::compare(const String& other, bool no_case) const {
- if(no_case)
- return detail::stricmp(m_str, other.m_str);
- return strcmp(m_str, other.m_str);
-}
-
-std::ostream& operator<<(std::ostream& stream, const String& in) {
- stream << in.c_str();
- return stream;
-}
-
-Approx::Approx(double value)
- : m_epsilon(static_cast<double>(std::numeric_limits<float>::epsilon()) * 100)
- , m_scale(1.0)
- , m_value(value) {}
-
-bool operator==(double lhs, Approx const& rhs) {
- // Thanks to Richard Harris for his help refining this formula
- return fabs(lhs - rhs.m_value) <
- rhs.m_epsilon * (rhs.m_scale + detail::my_max(fabs(lhs), fabs(rhs.m_value)));
-}
-
-String Approx::toString() const { return String("Approx( ") + doctest::toString(m_value) + " )"; }
-
-String toString(const char* in) { return String("\"") + (in ? in : "{null string}") + "\""; }
-String toString(bool in) { return in ? "true" : "false"; }
-String toString(float in) { return detail::fpToString(in, 5) + "f"; }
-String toString(double in) { return detail::fpToString(in, 10); }
-String toString(double long in) { return detail::fpToString(in, 15); }
-
-String toString(char in) {
- char buf[64];
- if(in < ' ')
- sprintf(buf, "%d", in);
- else
- sprintf(buf, "%c", in);
- return buf;
-}
-
-String toString(char unsigned in) {
- char buf[64];
- if(in < ' ')
- sprintf(buf, "%ud", in);
- else
- sprintf(buf, "%c", in);
- return buf;
-}
-
-String toString(int short in) {
- char buf[64];
- sprintf(buf, "%d", in);
- return buf;
-}
-
-String toString(int short unsigned in) {
- char buf[64];
- sprintf(buf, "%u", in);
- return buf;
-}
-
-String toString(int in) {
- char buf[64];
- sprintf(buf, "%d", in);
- return buf;
-}
-
-String toString(int unsigned in) {
- char buf[64];
- sprintf(buf, "%u", in);
- return buf;
-}
-
-String toString(int long in) {
- char buf[64];
- sprintf(buf, "%ld", in);
- return buf;
-}
-
-String toString(int long unsigned in) {
- char buf[64];
- sprintf(buf, "%lu", in);
- return buf;
-}
-
-#ifdef DOCTEST_CONFIG_WITH_LONG_LONG
-String toString(int long long in) {
- char buf[64];
- sprintf(buf, "%lld", in);
- return buf;
-}
-String toString(int long long unsigned in) {
- char buf[64];
- sprintf(buf, "%llu", in);
- return buf;
-}
-#endif // DOCTEST_CONFIG_WITH_LONG_LONG
-
-} // namespace doctest
-
-#if defined(DOCTEST_CONFIG_DISABLE)
-namespace doctest
-{
-Context::Context(int, const char* const*) {}
-Context::~Context() {}
-void Context::addFilter(const char*, const char*) {}
-void Context::setOption(const char*, int) {}
-void Context::setOption(const char*, const char*) {}
-bool Context::shouldExit() { return false; }
-int Context::run() { return 0; }
-} // namespace doctest
-#else // DOCTEST_CONFIG_DISABLE
-
-#if !defined(DOCTEST_CONFIG_COLORS_NONE)
-#if !defined(DOCTEST_CONFIG_COLORS_WINDOWS) && !defined(DOCTEST_CONFIG_COLORS_ANSI)
-#ifdef DOCTEST_PLATFORM_WINDOWS
-#define DOCTEST_CONFIG_COLORS_WINDOWS
-#else // linux
-#define DOCTEST_CONFIG_COLORS_ANSI
-#endif // platform
-#endif // DOCTEST_CONFIG_COLORS_WINDOWS && DOCTEST_CONFIG_COLORS_ANSI
-#endif // DOCTEST_CONFIG_COLORS_NONE
-
-#define DOCTEST_PRINTF_COLORED(buffer, color) \
- do { \
- if(buffer[0] != 0) { \
- doctest::detail::Color col(color); \
- printf("%s", buffer); \
- } \
- } while(doctest::detail::always_false())
-
-// the number of buckets used for the hash set
-#if !defined(DOCTEST_HASH_TABLE_NUM_BUCKETS)
-#define DOCTEST_HASH_TABLE_NUM_BUCKETS 1024
-#endif // DOCTEST_HASH_TABLE_NUM_BUCKETS
-
-// the buffer size used for snprintf() calls
-#if !defined(DOCTEST_SNPRINTF_BUFFER_LENGTH)
-#define DOCTEST_SNPRINTF_BUFFER_LENGTH 1024
-#endif // DOCTEST_SNPRINTF_BUFFER_LENGTH
-
-#if defined(_MSC_VER) || defined(__MINGW32__)
-extern "C" __declspec(dllimport) void __stdcall OutputDebugStringA(const char*);
-extern "C" __declspec(dllimport) int __stdcall IsDebuggerPresent();
-#endif // DOCTEST_PLATFORM_WINDOWS
-
-#ifdef DOCTEST_CONFIG_COLORS_ANSI
-#include <unistd.h>
-#endif // DOCTEST_CONFIG_COLORS_ANSI
-
-#ifdef DOCTEST_CONFIG_COLORS_WINDOWS
-
-// defines for a leaner windows.h
-#ifndef WIN32_MEAN_AND_LEAN
-#define WIN32_MEAN_AND_LEAN
-#endif // WIN32_MEAN_AND_LEAN
-#ifndef VC_EXTRA_LEAN
-#define VC_EXTRA_LEAN
-#endif // VC_EXTRA_LEAN
-#ifndef NOMINMAX
-#define NOMINMAX
-#endif // NOMINMAX
-
-// not sure what AfxWin.h is for - here I do what Catch does
-#ifdef __AFXDLL
-#include <AfxWin.h>
-#else
-#include <windows.h>
-#endif
-
-#endif // DOCTEST_CONFIG_COLORS_WINDOWS
-
-namespace doctest
-{
-namespace detail
-{
- bool TestData::operator==(const TestData& other) const {
- return m_line == other.m_line && strcmp(m_file, other.m_file) == 0;
- }
-
- void checkIfShouldThrow(const char* assert_name) {
- if(strncmp(assert_name, "REQUIRE", 7) == 0)
- throwException();
-
- if(strncmp(assert_name, "CHECK", 5) == 0 && getContextState()->abort_after > 0) {
- if(getContextState()->numFailedAssertions >= getContextState()->abort_after)
- throwException();
- }
- }
- void throwException() { throw doctest::detail::TestFailureException(); }
- bool always_false() { return false; }
- void* getNullPtr() { return 0; }
-
- // lowers ascii letters
- char tolower(const char c) { return ((c >= 'A' && c <= 'Z') ? static_cast<char>(c + 32) : c); }
-
- // matching of a string against a wildcard mask (case sensitivity configurable) taken from
- // http://www.emoticode.net/c/simple-wildcard-string-compare-globbing-function.html
- int wildcmp(const char* str, const char* wild, bool caseSensitive) {
- const char* cp = 0;
- const char* mp = 0;
-
- // rolled my own tolower() to not include more headers
- while((*str) && (*wild != '*')) {
- if((caseSensitive ? (*wild != *str) : (tolower(*wild) != tolower(*str))) &&
- (*wild != '?')) {
- return 0;
- }
- wild++;
- str++;
- }
-
- while(*str) {
- if(*wild == '*') {
- if(!*++wild) {
- return 1;
- }
- mp = wild;
- cp = str + 1;
- } else if((caseSensitive ? (*wild == *str) : (tolower(*wild) == tolower(*str))) ||
- (*wild == '?')) {
- wild++;
- str++;
- } else {
- wild = mp;
- str = cp++;
- }
- }
-
- while(*wild == '*') {
- wild++;
- }
- return !*wild;
- }
-
- // C string hash function (djb2) - taken from http://www.cse.yorku.ca/~oz/hash.html
- unsigned hashStr(unsigned const char* str) {
- unsigned long hash = 5381;
- char c;
-
- while((c = *str++))
- hash = ((hash << 5) + hash) + c; // hash * 33 + c
-
- return hash;
- }
-
- // checks if the name matches any of the filters (and can be configured what to do when empty)
- int matchesAny(const char* name, Vector<String> filters, int matchEmpty, bool caseSensitive) {
- if(filters.size() == 0 && matchEmpty)
- return 1;
- for(unsigned i = 0; i < filters.size(); ++i)
- if(wildcmp(name, filters[i].c_str(), caseSensitive))
- return 1;
- return 0;
- }
-
- template <class T>
- Vector<T>::Vector()
- : m_size(0)
- , m_capacity(0)
- , m_buffer(0) {}
-
- template <class T>
- Vector<T>::Vector(unsigned num, const T& val)
- : m_size(num)
- , m_capacity(num)
- , m_buffer(static_cast<T*>(malloc(sizeof(T) * m_capacity))) {
- for(unsigned i = 0; i < m_size; ++i)
- new(m_buffer + i) T(val);
- }
-
- template <class T>
- Vector<T>::Vector(const Vector& other)
- : m_size(other.m_size)
- , m_capacity(other.m_capacity)
- , m_buffer(static_cast<T*>(malloc(sizeof(T) * m_capacity))) {
- for(unsigned i = 0; i < m_size; ++i)
- new(m_buffer + i) T(other.m_buffer[i]);
- }
-
- template <class T>
- Vector<T>::~Vector() {
- for(unsigned i = 0; i < m_size; ++i)
- (*(m_buffer + i)).~T();
- free(m_buffer);
- }
-
- template <class T>
- Vector<T>& Vector<T>::operator=(const Vector& other) {
- if(this != &other) {
- for(unsigned i = 0; i < m_size; ++i)
- (*(m_buffer + i)).~T();
- free(m_buffer);
-
- m_size = other.m_size;
- m_capacity = other.m_capacity;
-
- m_buffer = static_cast<T*>(malloc(sizeof(T) * m_capacity));
- for(unsigned i = 0; i < m_size; ++i)
- new(m_buffer + i) T(other.m_buffer[i]);
- }
- return *this;
- }
-
- template <class T>
- void Vector<T>::clear() {
- for(unsigned i = 0; i < m_size; ++i)
- (*(m_buffer + i)).~T();
- m_size = 0;
- }
-
- template <class T>
- void Vector<T>::pop_back() {
- if(m_size > 0)
- (*(m_buffer + --m_size)).~T();
- }
-
- template <class T>
- void Vector<T>::push_back(const T& item) {
- if(m_size < m_capacity) {
- new(m_buffer + m_size++) T(item);
- } else {
- if(m_capacity == 0)
- m_capacity = 5; // initial capacity
- else
- m_capacity *= 2; // capacity growth factor
- T* temp = static_cast<T*>(malloc(sizeof(T) * m_capacity));
- for(unsigned i = 0; i < m_size; ++i) {
- new(temp + i) T(m_buffer[i]);
- (*(m_buffer + i)).~T();
- }
- new(temp + m_size++) T(item);
- free(m_buffer);
- m_buffer = temp;
- }
- }
-
- template <class T>
- void Vector<T>::resize(unsigned num, const T& val) {
- if(num < m_size) {
- for(unsigned i = num; i < m_size; ++i)
- (*(m_buffer + i)).~T();
- m_size = num;
- } else {
- if(num > m_capacity) {
- if(m_capacity == 0) {
- m_buffer = static_cast<T*>(malloc(sizeof(T) * num));
- } else {
- T* temp = static_cast<T*>(malloc(sizeof(T) * num));
- for(unsigned i = 0; i < m_size; ++i) {
- new(temp + i) T(m_buffer[i]);
- (*(m_buffer + i)).~T();
- }
- }
-
- for(unsigned i = m_size; i < num; ++i)
- new(m_buffer + i) T(val);
-
- m_size = num;
- m_capacity = num;
- }
- }
- }
-
- template <>
- unsigned Hash(const Subcase& in) {
- return hashStr(reinterpret_cast<unsigned const char*>(in.m_file)) ^ in.m_line;
- }
-
- template <>
- unsigned Hash(const String& in) {
- return hashStr(reinterpret_cast<unsigned const char*>(in.c_str()));
- }
-
- template <>
- unsigned Hash(const int& in) {
- return in;
- }
-
- // the current ContextState with which tests are being executed
- ContextState*& getContextState() {
- static ContextState* data = 0;
- return data;
- }
-
- TestAccessibleContextState* getTestsContextState() { return getContextState(); }
-
- Subcase::Subcase(const char* name, const char* file, int line)
- : m_name(name)
- , m_file(file)
- , m_line(line)
- , m_entered(false) {
- ContextState* s = getContextState();
-
- // if we have already completed it
- if(s->subcasesPassed.has(*this))
- return;
-
- // if a Subcase on the same level has already been entered
- if(s->subcasesEnteredLevels.has(s->subcasesCurrentLevel)) {
- s->subcasesHasSkipped = true;
- return;
- }
-
- s->subcasesStack.push_back(*this);
- s->hasLoggedCurrentTestStart = false;
- if(s->hasLoggedCurrentTestStart)
- logTestEnd();
-
- s->subcasesEnteredLevels.insert(s->subcasesCurrentLevel++);
- m_entered = true;
- }
-
- Subcase::~Subcase() {
- if(m_entered) {
- ContextState* s = getContextState();
-
- s->subcasesCurrentLevel--;
- // only mark the subcase as passed if no subcases have been skipped
- if(s->subcasesHasSkipped == false)
- s->subcasesPassed.insert(*this);
-
- s->subcasesStack.pop_back();
- s->hasLoggedCurrentTestStart = false;
- if(s->hasLoggedCurrentTestStart)
- logTestEnd();
- }
- }
-
- Subcase::Subcase(const Subcase& other)
- : m_name(other.m_name)
- , m_file(other.m_file)
- , m_line(other.m_line)
- , m_entered(other.m_entered) {}
-
- Subcase& Subcase::operator=(const Subcase& other) {
- m_name = other.m_name;
- m_file = other.m_file;
- m_line = other.m_line;
- m_entered = other.m_entered;
- return *this;
- }
-
- bool Subcase::operator==(const Subcase& other) const {
- return m_line == other.m_line && strcmp(m_file, other.m_file) == 0;
- }
-
- unsigned Hash(const TestData& in) {
- return hashStr(reinterpret_cast<unsigned const char*>(in.m_file)) ^ in.m_line;
- }
-
- // for sorting tests by file/line
- int fileOrderComparator(const void* a, const void* b) {
- const TestData* lhs = *static_cast<TestData* const*>(a);
- const TestData* rhs = *static_cast<TestData* const*>(b);
-#ifdef _MSC_VER
- // this is needed because MSVC gives different case for drive letters
- // for __FILE__ when evaluated in a header and a source file
- int res = stricmp(lhs->m_file, rhs->m_file);
-#else // _MSC_VER
- int res = strcmp(lhs->m_file, rhs->m_file);
-#endif // _MSC_VER
- if(res != 0)
- return res;
- return static_cast<int>(lhs->m_line - rhs->m_line);
- }
-
- // for sorting tests by suite/file/line
- int suiteOrderComparator(const void* a, const void* b) {
- const TestData* lhs = *static_cast<TestData* const*>(a);
- const TestData* rhs = *static_cast<TestData* const*>(b);
-
- int res = strcmp(lhs->m_suite, rhs->m_suite);
- if(res != 0)
- return res;
- return fileOrderComparator(a, b);
- }
-
- // for sorting tests by name/suite/file/line
- int nameOrderComparator(const void* a, const void* b) {
- const TestData* lhs = *static_cast<TestData* const*>(a);
- const TestData* rhs = *static_cast<TestData* const*>(b);
-
- int res = strcmp(lhs->m_name, rhs->m_name);
- if(res != 0)
- return res;
- return suiteOrderComparator(a, b);
- }
-
- // holds the current test suite
- const char*& getCurrentTestSuite() {
- static const char* data = 0;
- return data;
- }
-
- // sets the current test suite
- int setTestSuiteName(const char* name) {
- getCurrentTestSuite() = name;
- return 0;
- }
-
- // all the registered tests
- HashTable<TestData>& getRegisteredTests() {
- static HashTable<TestData> data(DOCTEST_HASH_TABLE_NUM_BUCKETS);
- return data;
- }
-
- // used by the macros for registering tests
- int regTest(funcType f, unsigned line, const char* file, const char* name) {
- getRegisteredTests().insert(TestData(getCurrentTestSuite(), name, f, file, line));
- return 0;
- }
-
- struct Color
- {
- 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
- };
- Color(Code code) { use(code); }
- ~Color() { use(None); }
-
- void use(Code code);
-
- private:
- Color(Color const& other);
- };
-
- void Color::use(Code
-#ifndef DOCTEST_CONFIG_COLORS_NONE
- code
-#endif // DOCTEST_CONFIG_COLORS_NONE
- ) {
- ContextState* p = getContextState();
- if(p->no_colors)
- return;
-#ifdef DOCTEST_CONFIG_COLORS_ANSI
- if(isatty(STDOUT_FILENO)) {
- const char* col = "";
- // clang-format off
- switch(code) {
- case Color::Red: col = "[0;31m"; break;
- case Color::Green: col = "[0;32m"; break;
- case Color::Blue: col = "[0:34m"; break;
- case Color::Cyan: col = "[0;36m"; break;
- case Color::Yellow: col = "[0;33m"; break;
- case Color::Grey: col = "[1;30m"; break;
- case Color::LightGrey: col = "[0;37m"; break;
- case Color::BrightRed: col = "[1;31m"; break;
- case Color::BrightGreen: col = "[1;32m"; break;
- case Color::BrightWhite: col = "[1;37m"; break;
- case Color::Bright: // invalid
- case Color::None:
- case Color::White:
- default: col = "[0m";
- }
- // clang-format on
- printf("\033%s", col);
- }
-#endif // DOCTEST_CONFIG_COLORS_ANSI
-
-#ifdef DOCTEST_CONFIG_COLORS_WINDOWS
- static HANDLE stdoutHandle(GetStdHandle(STD_OUTPUT_HANDLE));
- static WORD originalForegroundAttributes;
- static WORD originalBackgroundAttributes;
- static bool attrsInitted = false;
- if(!attrsInitted) {
- attrsInitted = true;
- 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);
- }
-
-#define DOCTEST_SET_ATTR(x) SetConsoleTextAttribute(stdoutHandle, x | originalBackgroundAttributes)
-
- // clang-format off
- switch (code) {
- case Color::White: DOCTEST_SET_ATTR(FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_BLUE); break;
- case Color::Red: DOCTEST_SET_ATTR(FOREGROUND_RED); break;
- case Color::Green: DOCTEST_SET_ATTR(FOREGROUND_GREEN); break;
- case Color::Blue: DOCTEST_SET_ATTR(FOREGROUND_BLUE); break;
- case Color::Cyan: DOCTEST_SET_ATTR(FOREGROUND_BLUE | FOREGROUND_GREEN); break;
- case Color::Yellow: DOCTEST_SET_ATTR(FOREGROUND_RED | FOREGROUND_GREEN); break;
- case Color::Grey: DOCTEST_SET_ATTR(0); break;
- case Color::LightGrey: DOCTEST_SET_ATTR(FOREGROUND_INTENSITY); break;
- case Color::BrightRed: DOCTEST_SET_ATTR(FOREGROUND_INTENSITY | FOREGROUND_RED); break;
- case Color::BrightGreen: DOCTEST_SET_ATTR(FOREGROUND_INTENSITY | FOREGROUND_GREEN); break;
- case Color::BrightWhite: DOCTEST_SET_ATTR(FOREGROUND_INTENSITY | FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_BLUE); break;
- case Color::None:
- case Color::Bright: // invalid
- default: DOCTEST_SET_ATTR(originalForegroundAttributes);
- }
-// clang-format on
-#undef DOCTEST_SET_ATTR
-#endif // DOCTEST_CONFIG_COLORS_WINDOWS
- }
-
- // this is needed because MSVC does not permit mixing 2 exception handling schemes in a function
- int callTestFunc(funcType f) {
- int res = EXIT_SUCCESS;
- try {
- f();
- if(getContextState()->numFailedAssertionsForCurrentTestcase)
- res = EXIT_FAILURE;
- } catch(const TestFailureException&) { res = EXIT_FAILURE; } catch(...) {
- DOCTEST_LOG_START();
- logTestCrashed();
- res = EXIT_FAILURE;
- }
- return res;
- }
-
- // depending on the current options this will remove the path of filenames
- const char* fileForOutput(const char* file) {
- if(getContextState()->no_path_in_filenames) {
- const char* back = strrchr(file, '\\');
- const char* forward = strrchr(file, '/');
- if(back || forward) {
- if(back > forward)
- forward = back;
- return forward + 1;
- }
- }
- return file;
- }
-
-#ifdef DOCTEST_PLATFORM_MAC
-#include <sys/types.h>
-#include <unistd.h>
-#include <sys/sysctl.h>
- // 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, 0, 0) != 0) {
- fprintf(stderr, "\n** Call to sysctl failed - unable to determine if debugger is "
- "active **\n\n");
- return false;
- }
- // We're being debugged if the P_TRACED flag is set.
- return ((info.kp_proc.p_flag & P_TRACED) != 0);
- }
-#elif defined(_MSC_VER) || defined(__MINGW32__)
- bool isDebuggerActive() { return ::IsDebuggerPresent() != 0; }
-#else
- bool isDebuggerActive() { return false; }
-#endif // Platform
-
-#ifdef DOCTEST_PLATFORM_WINDOWS
- void myOutputDebugString(const String& text) { ::OutputDebugStringA(text.c_str()); }
-#else
- // TODO: integration with XCode and other IDEs
- void myOutputDebugString(const String&) {}
-#endif // Platform
-
- const char* getSeparator() {
- return "===============================================================================\n";
- }
-
- void printToDebugConsole(const String& text) {
- if(isDebuggerActive())
- myOutputDebugString(text.c_str());
- }
-
- void addFailedAssert(const char* assert_name) {
- if(strncmp(assert_name, "WARN", 4) != 0) {
- getContextState()->numFailedAssertionsForCurrentTestcase++;
- getContextState()->numFailedAssertions++;
- }
- }
-
- void logTestStart(const char* name, const char* file, unsigned line) {
- const char* newLine = "\n";
-
- char loc[DOCTEST_SNPRINTF_BUFFER_LENGTH];
- DOCTEST_SNPRINTF(loc, DOCTEST_COUNTOF(loc), "%s(%d)\n", fileForOutput(file), line);
-
- char msg[DOCTEST_SNPRINTF_BUFFER_LENGTH];
- DOCTEST_SNPRINTF(msg, DOCTEST_COUNTOF(msg), "%s\n", name);
-
- DOCTEST_PRINTF_COLORED(getSeparator(), Color::Yellow);
- DOCTEST_PRINTF_COLORED(loc, Color::LightGrey);
- DOCTEST_PRINTF_COLORED(msg, Color::None);
-
- String subcaseStuff = "";
- Vector<Subcase>& subcasesStack = getContextState()->subcasesStack;
- String tabulation;
- for(unsigned i = 0; i < subcasesStack.size(); ++i) {
- tabulation += " ";
- char subcase[DOCTEST_SNPRINTF_BUFFER_LENGTH];
- DOCTEST_SNPRINTF(subcase, DOCTEST_COUNTOF(loc), "%s%s\n", tabulation.c_str(),
- subcasesStack[i].m_name);
- DOCTEST_PRINTF_COLORED(subcase, Color::None);
- subcaseStuff += subcase;
- }
-
- DOCTEST_PRINTF_COLORED(newLine, Color::None);
-
- printToDebugConsole(String(getSeparator()) + loc + msg + subcaseStuff.c_str() + newLine);
- }
-
- void logTestEnd() {}
-
- void logTestCrashed() {
- char msg[DOCTEST_SNPRINTF_BUFFER_LENGTH];
-
- DOCTEST_SNPRINTF(msg, DOCTEST_COUNTOF(msg), " TEST CASE FAILED! (threw exception)\n\n");
-
- DOCTEST_PRINTF_COLORED(msg, Color::Red);
-
- printToDebugConsole(String(msg));
- }
-
- void logAssert(bool passed, const char* decomposition, bool threw, const char* expr,
- const char* assert_name, const char* file, int line) {
- char loc[DOCTEST_SNPRINTF_BUFFER_LENGTH];
- DOCTEST_SNPRINTF(loc, DOCTEST_COUNTOF(loc), "%s(%d)", fileForOutput(file), line);
-
- char msg[DOCTEST_SNPRINTF_BUFFER_LENGTH];
- if(passed)
- DOCTEST_SNPRINTF(msg, DOCTEST_COUNTOF(msg), " PASSED!\n");
- else
- DOCTEST_SNPRINTF(msg, DOCTEST_COUNTOF(msg), " FAILED! %s\n",
- (threw ? "(threw exception)" : ""));
-
- char info1[DOCTEST_SNPRINTF_BUFFER_LENGTH];
- DOCTEST_SNPRINTF(info1, DOCTEST_COUNTOF(info1), " %s( %s )\n", assert_name, expr);
-
- char info2[DOCTEST_SNPRINTF_BUFFER_LENGTH];
- char info3[DOCTEST_SNPRINTF_BUFFER_LENGTH];
- info2[0] = 0;
- info3[0] = 0;
- if(!threw) {
- DOCTEST_SNPRINTF(info2, DOCTEST_COUNTOF(info2), "with expansion:\n");
- DOCTEST_SNPRINTF(info3, DOCTEST_COUNTOF(info3), " %s( %s )\n", assert_name,
- decomposition);
- }
-
- DOCTEST_PRINTF_COLORED(loc, Color::LightGrey);
- DOCTEST_PRINTF_COLORED(msg, passed ? Color::BrightGreen : Color::Red);
- DOCTEST_PRINTF_COLORED(info1, Color::Green);
- DOCTEST_PRINTF_COLORED(info2, Color::None);
- DOCTEST_PRINTF_COLORED(info3, Color::Green);
- DOCTEST_PRINTF_COLORED("\n", Color::None);
-
- printToDebugConsole(String(loc) + msg + info1 + info2 + info3 + "\n");
- }
-
- void logAssertThrows(bool threw, const char* expr, const char* assert_name, const char* file,
- int line) {
- char loc[DOCTEST_SNPRINTF_BUFFER_LENGTH];
- DOCTEST_SNPRINTF(loc, DOCTEST_COUNTOF(loc), "%s(%d)", fileForOutput(file), line);
-
- char msg[DOCTEST_SNPRINTF_BUFFER_LENGTH];
- if(threw)
- DOCTEST_SNPRINTF(msg, DOCTEST_COUNTOF(msg), " PASSED!\n");
- else
- DOCTEST_SNPRINTF(msg, DOCTEST_COUNTOF(msg), " FAILED!\n");
-
- char info1[DOCTEST_SNPRINTF_BUFFER_LENGTH];
- DOCTEST_SNPRINTF(info1, DOCTEST_COUNTOF(info1), " %s( %s )\n\n", assert_name, expr);
-
- DOCTEST_PRINTF_COLORED(loc, Color::LightGrey);
- DOCTEST_PRINTF_COLORED(msg, threw ? Color::BrightGreen : Color::Red);
- DOCTEST_PRINTF_COLORED(info1, Color::Green);
-
- printToDebugConsole(String(loc) + msg + info1);
- }
-
- void logAssertThrowsAs(bool threw, bool threw_as, const char* as, const char* expr,
- const char* assert_name, const char* file, int line) {
- char loc[DOCTEST_SNPRINTF_BUFFER_LENGTH];
- DOCTEST_SNPRINTF(loc, DOCTEST_COUNTOF(loc), "%s(%d)", fileForOutput(file), line);
-
- char msg[DOCTEST_SNPRINTF_BUFFER_LENGTH];
- if(threw_as)
- DOCTEST_SNPRINTF(msg, DOCTEST_COUNTOF(msg), " PASSED!\n");
- else
- DOCTEST_SNPRINTF(msg, DOCTEST_COUNTOF(msg), " FAILED! %s\n",
- (threw ? "(threw something else)" : "(didn't throw at all)"));
-
- char info1[DOCTEST_SNPRINTF_BUFFER_LENGTH];
- DOCTEST_SNPRINTF(info1, DOCTEST_COUNTOF(info1), " %s( %s, %s )\n\n", assert_name, expr,
- as);
-
- DOCTEST_PRINTF_COLORED(loc, Color::LightGrey);
- DOCTEST_PRINTF_COLORED(msg, threw_as ? Color::BrightGreen : Color::Red);
- DOCTEST_PRINTF_COLORED(info1, Color::Green);
-
- printToDebugConsole(String(loc) + msg + info1);
- }
-
- void logAssertNothrow(bool threw, const char* expr, const char* assert_name, const char* file,
- int line) {
- char loc[DOCTEST_SNPRINTF_BUFFER_LENGTH];
- DOCTEST_SNPRINTF(loc, DOCTEST_COUNTOF(loc), "%s(%d)", fileForOutput(file), line);
-
- char msg[DOCTEST_SNPRINTF_BUFFER_LENGTH];
- if(!threw)
- DOCTEST_SNPRINTF(msg, DOCTEST_COUNTOF(msg), " PASSED!\n");
- else
- DOCTEST_SNPRINTF(msg, DOCTEST_COUNTOF(msg), " FAILED!\n");
-
- char info1[DOCTEST_SNPRINTF_BUFFER_LENGTH];
- DOCTEST_SNPRINTF(info1, DOCTEST_COUNTOF(info1), " %s( %s )\n\n", assert_name, expr);
-
- DOCTEST_PRINTF_COLORED(loc, Color::LightGrey);
- DOCTEST_PRINTF_COLORED(msg, !threw ? Color::BrightGreen : Color::Red);
- DOCTEST_PRINTF_COLORED(info1, Color::Green);
-
- printToDebugConsole(String(loc) + msg + info1);
- }
-
- // the implementation of parseFlag()
- bool parseFlagImpl(int argc, const char* const* argv, const char* pattern) {
- for(int i = argc - 1; i >= 0; --i) {
- const char* temp = strstr(argv[i], pattern);
- if(temp && my_strlen(temp) == my_strlen(pattern)) {
- // eliminate strings in which the chars before the option are not '-'
- bool noBadCharsFound = true;
- while(temp != argv[i]) {
- if(*--temp != '-') {
- noBadCharsFound = false;
- break;
- }
- }
- if(noBadCharsFound)
- return true;
- }
- }
- return false;
- }
-
- // locates a flag on the command line
- bool parseFlag(int argc, const char* const* argv, const char* pattern) {
-#ifndef DOCTEST_CONFIG_NO_UNPREFIXED_OPTIONS
- if(!parseFlagImpl(argc, argv, pattern))
- return parseFlagImpl(argc, argv, pattern + 3); // 3 for "dt-"
- return true;
-#else // DOCTEST_CONFIG_NO_UNPREFIXED_OPTIONS
- return parseFlagImpl(argc, argv, pattern);
-#endif // DOCTEST_CONFIG_NO_UNPREFIXED_OPTIONS
- }
-
- // the implementation of parseOption()
- bool parseOptionImpl(int argc, const char* const* argv, const char* pattern, String& res) {
- for(int i = argc - 1; i >= 0; --i) {
- const char* temp = strstr(argv[i], pattern);
- if(temp) {
- // eliminate matches in which the chars before the option are not '-'
- bool noBadCharsFound = true;
- const char* curr = argv[i];
- while(curr != temp) {
- if(*curr++ != '-') {
- noBadCharsFound = false;
- break;
- }
- }
- if(noBadCharsFound) {
- temp += my_strlen(pattern);
- unsigned len = my_strlen(temp);
- if(len) {
- res = temp;
- return true;
- }
- }
- }
- }
- return false;
- }
-
- // parses an option and returns the string after the '=' character
- bool parseOption(int argc, const char* const* argv, const char* pattern, String& res,
- const String& defaultVal = String()) {
- res = defaultVal;
-#ifndef DOCTEST_CONFIG_NO_UNPREFIXED_OPTIONS
- if(!parseOptionImpl(argc, argv, pattern, res))
- return parseOptionImpl(argc, argv, pattern + 3, res); // 3 for "dt-"
- return true;
-#else // DOCTEST_CONFIG_NO_UNPREFIXED_OPTIONS
- return parseOptionImpl(argc, argv, pattern, res);
-#endif // DOCTEST_CONFIG_NO_UNPREFIXED_OPTIONS
- }
-
- // parses a comma separated list of words after a pattern in one of the arguments in argv
- bool parseCommaSepArgs(int argc, const char* const* argv, const char* pattern,
- Vector<String>& res) {
- String filtersString;
- if(parseOption(argc, argv, pattern, filtersString)) {
- // tokenize with "," as a separator
- char* pch = strtok(filtersString.c_str(), ","); // modifies the string
- while(pch != 0) {
- if(my_strlen(pch))
- res.push_back(pch);
- pch = strtok(0, ","); // uses the strtok() internal state to go to the next token
- }
- return true;
- }
- return false;
- }
-
- enum optionType
- {
- option_bool,
- option_int
- };
-
- // parses an int/bool option from the command line
- bool parseIntOption(int argc, const char* const* argv, const char* pattern, optionType type,
- int& res) {
- String parsedValue;
- if(parseOption(argc, argv, pattern, parsedValue)) {
- if(type == 0) {
- // boolean
- const char positive[][5] = {"1", "true", "on", "yes"}; // 5 - strlen("true") + 1
- const char negative[][6] = {"0", "false", "off", "no"}; // 6 - strlen("false") + 1
-
- // if the value matches any of the positive/negative possibilities
- for(unsigned i = 0; i < 4; i++) {
- if(parsedValue.compare(positive[i], true) == 0) {
- res = 1;
- return true;
- }
- if(parsedValue.compare(negative[i], true) == 0) {
- res = 0;
- return true;
- }
- }
- } else {
- // integer
- int theInt = atoi(parsedValue.c_str());
- if(theInt != 0) {
- res = theInt;
- return true;
- }
- }
- }
- return false;
- }
-
- void printVersion() {
- DOCTEST_PRINTF_COLORED("[doctest] ", Color::Cyan);
- printf("doctest version is \"%s\"\n", DOCTEST_VERSION);
- }
-
- void printHelp() {
- printVersion();
- DOCTEST_PRINTF_COLORED("[doctest]\n", Color::Cyan);
- DOCTEST_PRINTF_COLORED("[doctest] ", Color::Cyan);
- printf("boolean values: \"1/on/yes/true\" or \"0/off/no/false\"\n");
- DOCTEST_PRINTF_COLORED("[doctest] ", Color::Cyan);
- printf("filter values: \"str1,str2,str3\" (comma separated strings)\n");
- DOCTEST_PRINTF_COLORED("[doctest]\n", Color::Cyan);
- DOCTEST_PRINTF_COLORED("[doctest] ", Color::Cyan);
- printf("filters use wildcards for matching strings\n");
- DOCTEST_PRINTF_COLORED("[doctest] ", Color::Cyan);
- printf("something passes a filter if any of the strings in a filter matches\n");
- DOCTEST_PRINTF_COLORED("[doctest]\n", Color::Cyan);
- DOCTEST_PRINTF_COLORED("[doctest] ", Color::Cyan);
- printf("ALL FLAGS, OPTIONS AND FILTERS ALSO AVAILABLE WITH A \"dt-\" PREFIX!!!\n");
- DOCTEST_PRINTF_COLORED("[doctest]\n", Color::Cyan);
- DOCTEST_PRINTF_COLORED("[doctest] ", Color::Cyan);
- printf("Query flags - the program quits after them. Available:\n\n");
- printf(" -?, --help, -h prints this message\n");
- printf(" -v, --version prints the version\n");
- printf(" -c, --count prints the number of matching tests\n");
- printf(" -ltc, --list-test-cases lists all matching tests by name\n");
- printf(" -lts, --list-test-suites lists all matching test suites\n\n");
- //printf(" -hth, --hash-table-histogram undocumented\n");
- // ==================================================================================== << 79
- DOCTEST_PRINTF_COLORED("[doctest] ", Color::Cyan);
- printf("The available <int>/<string> options/filters are:\n\n");
- printf(" -tc, --test-case=<filters> filters tests by their name\n");
- printf(" -tce, --test-case-exclude=<filters> filters OUT tests by their name\n");
- printf(" -sf, --source-file=<filters> filters tests by their file\n");
- printf(" -sfe, --source-file-exclude=<filters> filters OUT tests by their file\n");
- printf(" -ts, --test-suite=<filters> filters tests by their test suite\n");
- printf(" -tse, --test-suite-exclude=<filters> filters OUT tests by their test suite\n");
- printf(" -ob, --order-by=<string> how the tests should be ordered\n");
- printf(" <string> - by [file/suite/name/rand]\n");
- printf(" -rs, --rand-seed=<int> seed for random ordering\n");
- printf(" -f, --first=<int> the first test passing the filters to\n");
- printf(" execute - for range-based execution\n");
- printf(" -l, --last=<int> the last test passing the filters to\n");
- printf(" execute - for range-based execution\n");
- printf(" -aa, --abort-after=<int> stop after <int> failed assertions\n\n");
- DOCTEST_PRINTF_COLORED("[doctest] ", Color::Cyan);
- printf("Bool options - can be used like flags and true is assumed. Available:\n\n");
- printf(" -s, --success=<bool> include successful assertions in output\n");
- printf(" -cs, --case-sensitive=<bool> filters being treated as case sensitive\n");
- printf(" -e, --exit=<bool> exits after the tests finish\n");
- printf(" -no, --no-overrides=<bool> disables procedural overrides of options\n");
- printf(" -nt, --no-throw=<bool> skips exceptions-related assert checks\n");
- printf(" -ne, --no-exitcode=<bool> returns (or exits) always with success\n");
- printf(" -nr, --no-run=<bool> skips all runtime doctest operations\n");
- printf(" -nc, --no-colors=<bool> disables colors in output\n");
- printf(" -nb, --no-breaks=<bool> disables breakpoints in debuggers\n");
- printf(" -npf, --no-path-filenames=<bool> only filenames and no paths in output\n\n");
- // ==================================================================================== << 79
-
- DOCTEST_PRINTF_COLORED("[doctest] ", Color::Cyan);
- printf("for more information visit the project documentation\n\n");
- }
-} // namespace detail
-
-Context::Context(int argc, const char* const* argv)
- : p(new detail::ContextState) {
- using namespace detail;
-
- parseArgs(argc, argv, true);
-
- p->help = false;
- p->version = false;
- p->count = false;
- p->list_test_cases = false;
- p->list_test_suites = false;
- p->hash_table_histogram = false;
- if(parseFlag(argc, argv, "dt-help") || parseFlag(argc, argv, "dt-h") ||
- parseFlag(argc, argv, "dt-?")) {
- p->help = true;
- p->exit = true;
- }
- if(parseFlag(argc, argv, "dt-version") || parseFlag(argc, argv, "dt-v")) {
- p->version = true;
- p->exit = true;
- }
- if(parseFlag(argc, argv, "dt-count") || parseFlag(argc, argv, "dt-c")) {
- p->count = true;
- p->exit = true;
- }
- if(parseFlag(argc, argv, "dt-list-test-cases") || parseFlag(argc, argv, "dt-ltc")) {
- p->list_test_cases = true;
- p->exit = true;
- }
- if(parseFlag(argc, argv, "dt-list-test-suites") || parseFlag(argc, argv, "dt-lts")) {
- p->list_test_suites = true;
- p->exit = true;
- }
- if(parseFlag(argc, argv, "dt-hash-table-histogram") || parseFlag(argc, argv, "dt-hth")) {
- p->hash_table_histogram = true;
- p->exit = true;
- }
-}
-
-Context::~Context() { delete p; }
-
-// parses args
-void Context::parseArgs(int argc, const char* const* argv, bool withDefaults) {
- using namespace detail;
-
- // clang-format off
- parseCommaSepArgs(argc, argv, "dt-source-file=", p->filters[0]);
- parseCommaSepArgs(argc, argv, "dt-sf=", p->filters[0]);
- parseCommaSepArgs(argc, argv, "dt-source-file-exclude=",p->filters[1]);
- parseCommaSepArgs(argc, argv, "dt-sfe=", p->filters[1]);
- parseCommaSepArgs(argc, argv, "dt-test-suite=", p->filters[2]);
- parseCommaSepArgs(argc, argv, "dt-ts=", p->filters[2]);
- parseCommaSepArgs(argc, argv, "dt-test-suite-exclude=", p->filters[3]);
- parseCommaSepArgs(argc, argv, "dt-tse=", p->filters[3]);
- parseCommaSepArgs(argc, argv, "dt-test-case=", p->filters[4]);
- parseCommaSepArgs(argc, argv, "dt-tc=", p->filters[4]);
- parseCommaSepArgs(argc, argv, "dt-test-case-exclude=", p->filters[5]);
- parseCommaSepArgs(argc, argv, "dt-tce=", p->filters[5]);
- // clang-format on
-
- int intRes = 0;
- String strRes;
-
-#define DOCTEST_PARSE_AS_BOOL_OR_FLAG(name, sname, var, default) \
- if(parseIntOption(argc, argv, DOCTEST_STR_CONCAT_TOSTR(name, =), option_bool, intRes) || \
- parseIntOption(argc, argv, DOCTEST_STR_CONCAT_TOSTR(sname, =), option_bool, intRes)) \
- p->var = !!intRes; \
- else if(parseFlag(argc, argv, #name) || parseFlag(argc, argv, #sname)) \
- p->var = 1; \
- else if(withDefaults) \
- p->var = default
-
-#define DOCTEST_PARSE_INT_OPTION(name, sname, var, default) \
- if(parseIntOption(argc, argv, DOCTEST_STR_CONCAT_TOSTR(name, =), option_int, intRes) || \
- parseIntOption(argc, argv, DOCTEST_STR_CONCAT_TOSTR(sname, =), option_int, intRes)) \
- p->var = intRes; \
- else if(withDefaults) \
- p->var = default
-
-#define DOCTEST_PARSE_STR_OPTION(name, sname, var, default) \
- if(parseOption(argc, argv, DOCTEST_STR_CONCAT_TOSTR(name, =), strRes, default) || \
- parseOption(argc, argv, DOCTEST_STR_CONCAT_TOSTR(sname, =), strRes, default) || \
- withDefaults) \
- p->var = strRes
-
- // clang-format off
- DOCTEST_PARSE_STR_OPTION(dt-order-by, dt-ob, order_by, "file");
- DOCTEST_PARSE_INT_OPTION(dt-rand-seed, dt-rs, rand_seed, 0);
-
- DOCTEST_PARSE_INT_OPTION(dt-first, dt-f, first, 1);
- DOCTEST_PARSE_INT_OPTION(dt-last, dt-l, last, 0);
-
- DOCTEST_PARSE_INT_OPTION(dt-abort-after, dt-aa, abort_after, 0);
-
- DOCTEST_PARSE_AS_BOOL_OR_FLAG(dt-success, dt-s, success, 0);
- DOCTEST_PARSE_AS_BOOL_OR_FLAG(dt-case-sensitive, dt-cs, case_sensitive, 0);
- DOCTEST_PARSE_AS_BOOL_OR_FLAG(dt-exit, dt-e, exit, 0);
- DOCTEST_PARSE_AS_BOOL_OR_FLAG(dt-no-overrides, dt-no, no_overrides, 0);
- DOCTEST_PARSE_AS_BOOL_OR_FLAG(dt-no-throw, dt-nt, no_throw, 0);
- DOCTEST_PARSE_AS_BOOL_OR_FLAG(dt-no-exitcode, dt-ne, no_exitcode, 0);
- DOCTEST_PARSE_AS_BOOL_OR_FLAG(dt-no-run, dt-nr, no_run, 0);
- DOCTEST_PARSE_AS_BOOL_OR_FLAG(dt-no-colors, dt-nc, no_colors, 0);
- DOCTEST_PARSE_AS_BOOL_OR_FLAG(dt-no-breaks, dt-nb, no_breaks, 0);
- DOCTEST_PARSE_AS_BOOL_OR_FLAG(dt-no-path-filenames, dt-npf, no_path_in_filenames, 0);
-// clang-format on
-
-#undef DOCTEST_PARSE_STR_OPTION
-#undef DOCTEST_PARSE_INT_OPTION
-#undef DOCTEST_PARSE_AS_BOOL_OR_FLAG
-}
-
-// allows the user to add procedurally to the filters from the command line
-void Context::addFilter(const char* filter, const char* value) { setOption(filter, value); }
-
-// allows the user to override procedurally the int/bool options from the command line
-void Context::setOption(const char* option, int value) {
- setOption(option, toString(value).c_str());
-}
-
-// allows the user to override procedurally the string options from the command line
-void Context::setOption(const char* option, const char* value) {
- using namespace detail;
-
- if(!p->no_overrides) {
- String argv = String(option) + "=" + value;
- const char* lvalue = argv.c_str();
- parseArgs(1, &lvalue);
- }
-}
-
-// users should query this in their main() and exit the program if true
-bool Context::shouldExit() { return p->exit; }
-
-// the main function that does all the filtering and test running
-int Context::run() {
- using namespace detail;
-
- getContextState() = p;
- p->resetRunData();
-
- // handle version, help and no_run
- if(p->no_run || p->version || p->help) {
- if(p->version)
- printVersion();
- if(p->help)
- printHelp();
-
- return EXIT_SUCCESS;
- }
-
- printVersion();
- DOCTEST_PRINTF_COLORED("[doctest] ", Color::Cyan);
- printf("run with \"-dt-help\" for options\n");
-
- unsigned i = 0; // counter used for loops - here for VC6
- const Vector<Vector<TestData> >& buckets = getRegisteredTests().getBuckets();
-
- Vector<const TestData*> testArray;
- for(i = 0; i < buckets.size(); i++)
- for(unsigned k = 0; k < buckets[i].size(); k++)
- testArray.push_back(&buckets[i][k]);
-
- if(p->hash_table_histogram) {
- // find the most full bucket
- unsigned maxInBucket = 1;
- for(i = 0; i < buckets.size(); i++)
- if(buckets[i].size() > maxInBucket)
- maxInBucket = buckets[i].size();
-
- // print a prettified histogram
- DOCTEST_PRINTF_COLORED("[doctest] ", Color::Cyan);
- printf("hash table bucket histogram\n");
- printf("============================================================\n");
- printf("#bucket |count| relative count\n");
- printf("============================================================\n");
- for(i = 0; i < buckets.size(); i++) {
- printf("bucket %4d |%4d |", static_cast<int>(i), buckets[i].size());
-
- float ratio = static_cast<float>(buckets[i].size()) / static_cast<float>(maxInBucket);
- unsigned numStars = static_cast<unsigned>(ratio * 41);
- for(unsigned k = 0; k < numStars; ++k)
- printf("*");
- printf("\n");
- }
- printf("\n");
- return EXIT_SUCCESS;
- }
-
- // sort the collected records
- if(p->order_by.compare("file", true) == 0) {
- qsort(testArray.data(), testArray.size(), sizeof(TestData*), fileOrderComparator);
- } else if(p->order_by.compare("suite", true) == 0) {
- qsort(testArray.data(), testArray.size(), sizeof(TestData*), suiteOrderComparator);
- } else if(p->order_by.compare("name", true) == 0) {
- qsort(testArray.data(), testArray.size(), sizeof(TestData*), nameOrderComparator);
- } else if(p->order_by.compare("rand", true) == 0) {
- srand(p->rand_seed);
-
- // random_shuffle implementation
- const TestData** first = testArray.data();
- for(i = testArray.size() - 1; i > 0; --i) {
- int idxToSwap = rand() % (i + 1);
-
- const TestData* temp = first[i];
-
- first[i] = first[idxToSwap];
- first[idxToSwap] = temp;
- }
- }
-
- if(p->list_test_cases) {
- DOCTEST_PRINTF_COLORED("[doctest] ", Color::Cyan);
- printf("listing all test case names\n");
- }
-
- HashTable<String> testSuitesPassingFilters(100);
- if(p->list_test_suites) {
- DOCTEST_PRINTF_COLORED("[doctest] ", Color::Cyan);
- printf("listing all test suites\n");
- }
-
- unsigned numTestsPassingFilters = 0;
- unsigned numFailed = 0;
- // invoke the registered functions if they match the filter criteria (or just count them)
- for(i = 0; i < testArray.size(); i++) {
- const TestData& data = *testArray[i];
- if(!matchesAny(data.m_file, p->filters[0], 1, p->case_sensitive))
- continue;
- if(matchesAny(data.m_file, p->filters[1], 0, p->case_sensitive))
- continue;
- if(!matchesAny(data.m_suite, p->filters[2], 1, p->case_sensitive))
- continue;
- if(matchesAny(data.m_suite, p->filters[3], 0, p->case_sensitive))
- continue;
- if(!matchesAny(data.m_name, p->filters[4], 1, p->case_sensitive))
- continue;
- if(matchesAny(data.m_name, p->filters[5], 0, p->case_sensitive))
- continue;
-
- numTestsPassingFilters++;
-
- // do not execute the test if we are to only count the number of filter passing tests
- if(p->count)
- continue;
-
- // print the name of the test and don't execute it
- if(p->list_test_cases) {
- printf("%s\n", data.m_name);
- continue;
- }
-
- // print the name of the test suite if not done already and don't execute it
- if(p->list_test_suites) {
- if(!testSuitesPassingFilters.has(data.m_suite)) {
- printf("%s\n", data.m_suite);
- testSuitesPassingFilters.insert(data.m_suite);
- }
- continue;
- }
-
- // skip the test if it is not in the execution range
- if((p->last < numTestsPassingFilters && p->first <= p->last) ||
- (p->first > numTestsPassingFilters))
- continue;
-
- // execute the test if it passes all the filtering
- {
-#ifdef _MSC_VER
-//__try {
-#endif // _MSC_VER
-
- p->currentTest = &data;
-
- // if logging successful tests - force the start log
- p->hasLoggedCurrentTestStart = false;
- if(p->success)
- DOCTEST_LOG_START();
-
- unsigned didFail = 0;
- p->subcasesPassed.clear();
- do {
- // reset the assertion state
- p->numAssertionsForCurrentTestcase = 0;
- p->numFailedAssertionsForCurrentTestcase = 0;
-
- // reset some of the fields for subcases (except for the set of fully passed ones)
- p->subcasesHasSkipped = false;
- p->subcasesCurrentLevel = 0;
- p->subcasesEnteredLevels.clear();
-
- // execute the test
- didFail += callTestFunc(data.m_f);
- p->numAssertions += p->numAssertionsForCurrentTestcase;
-
- // exit this loop if enough assertions have failed
- if(p->abort_after > 0 && p->numFailedAssertions >= p->abort_after)
- p->subcasesHasSkipped = false;
-
- // if the start has been logged
- if(p->hasLoggedCurrentTestStart)
- logTestEnd();
- p->hasLoggedCurrentTestStart = false;
-
- } while(p->subcasesHasSkipped == true);
-
- if(didFail > 0)
- numFailed++;
-
- // stop executing tests if enough assertions have failed
- if(p->abort_after > 0 && p->numFailedAssertions >= p->abort_after)
- break;
-
-#ifdef _MSC_VER
-//} __except(1) {
-// printf("Unknown SEH exception caught!\n");
-// numFailed++;
-//}
-#endif // _MSC_VER
- }
- }
-
- DOCTEST_PRINTF_COLORED(getSeparator(), Color::Yellow);
- if(p->count || p->list_test_cases || p->list_test_suites) {
- DOCTEST_PRINTF_COLORED("[doctest] ", Color::Cyan);
- printf("number of tests passing the current filters: %d\n", numTestsPassingFilters);
- } else {
- char buff[DOCTEST_SNPRINTF_BUFFER_LENGTH];
-
- DOCTEST_PRINTF_COLORED("[doctest] ", Color::Cyan);
-
- DOCTEST_SNPRINTF(buff, DOCTEST_COUNTOF(buff), "test cases: %4d", numTestsPassingFilters);
- DOCTEST_PRINTF_COLORED(buff, Color::None);
- DOCTEST_SNPRINTF(buff, DOCTEST_COUNTOF(buff), " | ");
- DOCTEST_PRINTF_COLORED(buff, Color::None);
- DOCTEST_SNPRINTF(buff, DOCTEST_COUNTOF(buff), "%4d passed",
- numTestsPassingFilters - numFailed);
- DOCTEST_PRINTF_COLORED(buff, Color::Green);
- DOCTEST_SNPRINTF(buff, DOCTEST_COUNTOF(buff), " | ");
- DOCTEST_PRINTF_COLORED(buff, Color::None);
- DOCTEST_SNPRINTF(buff, DOCTEST_COUNTOF(buff), "%4d failed\n", numFailed);
- DOCTEST_PRINTF_COLORED(buff, Color::Red);
-
- DOCTEST_PRINTF_COLORED("[doctest] ", Color::Cyan);
-
- DOCTEST_SNPRINTF(buff, DOCTEST_COUNTOF(buff), "assertions: %4d", p->numAssertions);
- DOCTEST_PRINTF_COLORED(buff, Color::None);
- DOCTEST_SNPRINTF(buff, DOCTEST_COUNTOF(buff), " | ");
- DOCTEST_PRINTF_COLORED(buff, Color::None);
- DOCTEST_SNPRINTF(buff, DOCTEST_COUNTOF(buff), "%4d passed",
- p->numAssertions - p->numFailedAssertions);
- DOCTEST_PRINTF_COLORED(buff, Color::Green);
- DOCTEST_SNPRINTF(buff, DOCTEST_COUNTOF(buff), " | ");
- DOCTEST_PRINTF_COLORED(buff, Color::None);
- DOCTEST_SNPRINTF(buff, DOCTEST_COUNTOF(buff), "%4d failed\n", p->numFailedAssertions);
- DOCTEST_PRINTF_COLORED(buff, Color::Red);
- }
-
- if(numFailed && !p->no_exitcode)
- return EXIT_FAILURE;
- return EXIT_SUCCESS;
-}
-} // namespace doctest
-
-#endif // DOCTEST_CONFIG_DISABLE
-#endif // DOCTEST_LIBRARY_IMPLEMENTATION
-#endif // DOCTEST_CONFIG_IMPLEMENT
-
-// == THIS SUPPLIES A MAIN FUNCTION AND SHOULD BE DONE ONLY IN ONE TRANSLATION UNIT
-#if defined(DOCTEST_CONFIG_IMPLEMENT_WITH_MAIN) && !defined(DOCTEST_MAIN_CONFIGURED)
-#define DOCTEST_MAIN_CONFIGURED
-int main(int argc, char** argv) { return doctest::Context(argc, argv).run(); }
-#endif // DOCTEST_MAIN_CONFIGURED
-
-#if defined(__clang__)
-#pragma clang diagnostic pop
-#endif // __clang__
-
-#if defined(__GNUC__) && !defined(__clang__)
-#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ > 6)
-#pragma GCC diagnostic pop
-#endif // > gcc 4.6
-#endif // __GNUC__
-
-#ifdef _MSC_VER
-#pragma warning(pop)
-#endif // _MSC_VER
+//
+// doctest.h - the lightest feature rich C++ single header testing framework
+//
+// Copyright (c) 2016 Viktor Kirilov
+//
+// Distributed under the MIT Software License
+// See accompanying file LICENSE.txt or copy at
+// https://opensource.org/licenses/MIT
+//
+// The documentation can be found at the library's page:
+// https://github.com/onqtam/doctest/blob/master/doc/markdown/readme.md
+//
+// The library is heavily influenced by Catch - https://github.com/philsquared/Catch
+// which uses the Boost Software License - Version 1.0
+// see here - https://github.com/philsquared/Catch/blob/master/LICENSE_1_0.txt
+// The concept of subcases (sections in Catch) and expression decomposition are from there.
+// Some parts of the code are taken directly:
+// - stringification - the detection of "ostream& operator<<(ostream&, const T&)" and the StringMaker class
+// - the Approx() helper class for floating point comparison
+// - colors in the console
+// - breaking into a debugger
+
+// =================================================================================================
+// =================================================================================================
+// =================================================================================================
+
+// Suppress this globally - there is no way to silence it in the expression decomposition macros
+// _Pragma() in macros doesn't work for the c++ front-end of g++
+// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=55578
+// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=69543
+// Also the warning is completely worthless nowadays - http://stackoverflow.com/questions/14016993
+#if defined(__GNUC__) && !defined(__clang__)
+#pragma GCC diagnostic ignored "-Waggregate-return"
+#endif
+
+#if defined(__clang__)
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wpadded"
+#pragma clang diagnostic ignored "-Wglobal-constructors"
+#pragma clang diagnostic ignored "-Wexit-time-destructors"
+#pragma clang diagnostic ignored "-Wmissing-prototypes"
+#pragma clang diagnostic ignored "-Wsign-conversion"
+#pragma clang diagnostic ignored "-Wshorten-64-to-32"
+#pragma clang diagnostic ignored "-Wmissing-variable-declarations"
+#pragma clang diagnostic ignored "-Wcovered-switch-default"
+#pragma clang diagnostic ignored "-Wmissing-noreturn"
+#endif // __clang__
+
+#if defined(__GNUC__) && !defined(__clang__)
+#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ > 6)
+#pragma GCC diagnostic push
+#endif // > gcc 4.6
+#pragma GCC diagnostic ignored "-Wconversion"
+#pragma GCC diagnostic ignored "-Weffc++"
+#pragma GCC diagnostic ignored "-Wsign-conversion"
+#pragma GCC diagnostic ignored "-Wstrict-overflow"
+#pragma GCC diagnostic ignored "-Wmissing-declarations"
+#pragma GCC diagnostic ignored "-Winline"
+#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ > 6)
+#pragma GCC diagnostic ignored "-Wzero-as-null-pointer-constant"
+#endif // > gcc 4.6
+//#pragma GCC diagnostic ignored "-Wlong-long"
+#endif // __GNUC__
+
+#ifdef _MSC_VER
+#pragma warning(push)
+#pragma warning(disable : 4996) // The compiler encountered a deprecated declaration
+#pragma warning(disable : 4267) // 'var' : conversion from 'size_t' to 'type', possible loss of data
+#pragma warning(disable : 4706) // assignment within conditional expression
+#pragma warning(disable : 4512) // 'class' : assignment operator could not be generated
+#pragma warning(disable : 4127) // conditional expression is constant
+#endif // _MSC_VER
+
+#ifndef DOCTEST_LIBRARY_INCLUDED
+#define DOCTEST_LIBRARY_INCLUDED
+
+#define DOCTEST_VERSION_MAJOR 1
+#define DOCTEST_VERSION_MINOR 0
+#define DOCTEST_VERSION_PATCH 0
+#define DOCTEST_VERSION "1.0.0"
+
+// internal macros for string concatenation and anonymous variable name generation
+#define DOCTEST_CONCAT_IMPL(s1, s2) s1##s2
+#define DOCTEST_CONCAT(s1, s2) DOCTEST_CONCAT_IMPL(s1, s2)
+#ifdef __COUNTER__ // not standard and may be missing for some compilers
+#define DOCTEST_ANONYMOUS(x) DOCTEST_CONCAT(x, __COUNTER__)
+#else // __COUNTER__
+#define DOCTEST_ANONYMOUS(x) DOCTEST_CONCAT(x, __LINE__)
+#endif // __COUNTER__
+
+// internal macro for making a string
+#define DOCTEST_TOSTR_IMPL(x) #x
+#define DOCTEST_TOSTR(x) DOCTEST_TOSTR_IMPL(x)
+
+// internal macro for concatenating 2 literals and making the result a string
+#define DOCTEST_STR_CONCAT_TOSTR(s1, s2) DOCTEST_TOSTR(s1) DOCTEST_TOSTR(s2)
+
+// not using __APPLE__ because... this is how Catch does it
+#if defined(__MAC_OS_X_VERSION_MIN_REQUIRED)
+#define DOCTEST_PLATFORM_MAC
+#elif defined(__IPHONE_OS_VERSION_MIN_REQUIRED)
+#define DOCTEST_PLATFORM_IPHONE
+#elif defined(_WIN32) || defined(_MSC_VER)
+#define DOCTEST_PLATFORM_WINDOWS
+#else
+#define DOCTEST_PLATFORM_LINUX
+#endif
+
+#define DOCTEST_COUNTOF(x) (sizeof(x) / sizeof(x[0]))
+
+#define DOCTEST_GCS doctest::detail::getTestsContextState
+
+// snprintf() not in the C++98 standard
+#ifdef _MSC_VER
+#define DOCTEST_SNPRINTF _snprintf
+#else
+#define DOCTEST_SNPRINTF snprintf
+#endif
+
+// for anything below Visual Studio 2005 (VC++6 has no __debugbreak() - not sure about VS 2003)
+#if defined(_MSC_VER) && _MSC_VER < 1400
+#define __debugbreak() __asm { int 3}
+#endif
+
+#ifdef DOCTEST_PLATFORM_MAC
+// The following code snippet based on:
+// http://cocoawithlove.com/2008/03/break-into-debugger.html
+#ifdef DEBUG
+#if defined(__ppc64__) || defined(__ppc__)
+#define DOCTEST_BREAK_INTO_DEBUGGER() \
+ if(doctest::detail::isDebuggerActive() && !DOCTEST_GCS()->no_breaks) \
+ __asm__("li r0, 20\nsc\nnop\nli r0, 37\nli r4, 2\nsc\nnop\n" : : : "memory", "r0", "r3", "r4")
+#else // __ppc64__ || __ppc__
+#define DOCTEST_BREAK_INTO_DEBUGGER() \
+ if(doctest::detail::isDebuggerActive() && !DOCTEST_GCS()->no_breaks) \
+ __asm__("int $3\n" : :)
+#endif // __ppc64__ || __ppc__
+#endif // DEBUG
+#elif defined(_MSC_VER)
+#define DOCTEST_BREAK_INTO_DEBUGGER() \
+ if(doctest::detail::isDebuggerActive() && !DOCTEST_GCS()->no_breaks) \
+ __debugbreak()
+#elif defined(__MINGW32__)
+extern "C" __declspec(dllimport) void __stdcall DebugBreak();
+#define DOCTEST_BREAK_INTO_DEBUGGER() \
+ if(doctest::detail::isDebuggerActive() && !DOCTEST_GCS()->no_breaks) \
+ ::DebugBreak()
+#else // linux
+#define DOCTEST_BREAK_INTO_DEBUGGER() ((void)0)
+#endif // linux
+
+#ifdef __clang__
+#include <ciso646>
+#endif // __clang__
+
+#ifdef _LIBCPP_VERSION
+#include <iosfwd>
+#else // _LIBCPP_VERSION
+#ifndef DOCTEST_CONFIG_USE_IOSFWD
+namespace std
+{
+template <class charT>
+struct char_traits;
+template <>
+struct char_traits<char>;
+template <class charT, class traits>
+class basic_ostream;
+typedef basic_ostream<char, char_traits<char> > ostream;
+}
+#else // DOCTEST_CONFIG_USE_IOSFWD
+#include <iosfwd>
+#endif // DOCTEST_CONFIG_USE_IOSFWD
+#endif // _LIBCPP_VERSION
+
+#ifndef DOCTEST_CONFIG_WITH_LONG_LONG
+#if __cplusplus >= 201103L || (defined(_MSC_VER) && (_MSC_VER >= 1400))
+#define DOCTEST_CONFIG_WITH_LONG_LONG
+#endif // __cplusplus / _MSC_VER
+#endif // DOCTEST_CONFIG_WITH_LONG_LONG
+
+namespace doctest
+{
+class String
+{
+ char* m_str;
+
+ void copy(const String& other);
+
+public:
+ String(const char* in = "");
+ String(const String& other);
+ ~String();
+
+ String& operator=(const String& other);
+
+ String operator+(const String& other) const;
+ String& operator+=(const String& other);
+
+ char& operator[](unsigned pos) { return m_str[pos]; }
+ const char& operator[](unsigned pos) const { return m_str[pos]; }
+
+ char* c_str() { return m_str; }
+ const char* c_str() const { return m_str; }
+
+ unsigned size() const;
+ unsigned length() const;
+
+ int compare(const char* other, bool no_case = false) const;
+ int compare(const String& other, bool no_case = false) const;
+};
+
+// clang-format off
+inline bool operator==(const String& lhs, const String& rhs) { return lhs.compare(rhs) == 0; }
+inline bool operator!=(const String& lhs, const String& rhs) { return lhs.compare(rhs) != 0; }
+inline bool operator< (const String& lhs, const String& rhs) { return lhs.compare(rhs) < 0; }
+inline bool operator> (const String& lhs, const String& rhs) { return lhs.compare(rhs) > 0; }
+inline bool operator<=(const String& lhs, const String& rhs) { return (lhs != rhs) ? lhs.compare(rhs) < 0 : true; }
+inline bool operator>=(const String& lhs, const String& rhs) { return (lhs != rhs) ? lhs.compare(rhs) > 0 : true; }
+// clang-format on
+
+std::ostream& operator<<(std::ostream& stream, const String& in);
+
+namespace detail
+{
+ template <bool>
+ struct STATIC_ASSERT_No_output_stream_operator_found_for_type;
+
+ template <>
+ struct STATIC_ASSERT_No_output_stream_operator_found_for_type<true>
+ {};
+
+ namespace has_insertion_operator_impl
+ {
+ typedef char no;
+ typedef char yes[2];
+
+ template <bool in>
+ void f() {
+ STATIC_ASSERT_No_output_stream_operator_found_for_type<in>();
+ }
+
+ struct any_t
+ {
+ template <typename T>
+ any_t(const T&) {
+ f<false>();
+ }
+ };
+
+ yes& testStreamable(std::ostream&);
+ no testStreamable(no);
+
+ no operator<<(const std::ostream&, const any_t&);
+
+ template <typename T>
+ struct has_insertion_operator
+ {
+ static std::ostream& s;
+ static const T& t;
+// for anything below Visual Studio 2005 (VC++6 is troublesome - not sure about VS 2003)
+#if defined(_MSC_VER) && _MSC_VER < 1400
+ enum
+ {
+ value
+ };
+#else // _MSC_VER
+ static const bool value = sizeof(testStreamable(s << t)) == sizeof(yes);
+#endif // _MSC_VER
+ };
+ } // namespace has_insertion_operator_impl
+
+ template <typename T>
+ struct has_insertion_operator : has_insertion_operator_impl::has_insertion_operator<T>
+ {};
+
+ std::ostream* createStream();
+ String getStreamResult(std::ostream*);
+ void freeStream(std::ostream*);
+
+ template <bool C>
+ struct StringMakerBase
+ {
+ template <typename T>
+ static String convert(const T&) {
+ return "{?}";
+ }
+ };
+
+ template <>
+ struct StringMakerBase<true>
+ {
+ template <typename T>
+ static String convert(const T& in) {
+ std::ostream* stream = createStream();
+ *stream << in;
+ String result = getStreamResult(stream);
+ freeStream(stream);
+ return result;
+ }
+ };
+
+ String rawMemoryToString(const void* object, unsigned size);
+
+ template <typename T>
+ String rawMemoryToString(const T& object) {
+ return rawMemoryToString(&object, sizeof(object));
+ }
+} // namespace detail
+
+// for anything below Visual Studio 2005 (VC++6 is troublesome - not sure about VS 2003)
+#if defined(_MSC_VER) && _MSC_VER < 1400
+template <typename T>
+struct StringMaker : detail::StringMakerBase<false>
+{};
+#else // _MSC_VER
+template <typename T>
+struct StringMaker : detail::StringMakerBase<detail::has_insertion_operator<T>::value>
+{};
+#endif // _MSC_VER
+
+// not for anything below Visual Studio 2005 (VC++6 is troublesome - not sure about VS 2003)
+#if defined(_MSC_VER) && _MSC_VER >= 1400
+template <typename T>
+struct StringMaker<T*>
+{
+ template <typename U>
+ static String convert(U* p) {
+ if(!p)
+ return "NULL";
+ else
+ return detail::rawMemoryToString(p);
+ }
+};
+
+template <typename R, typename C>
+struct StringMaker<R C::*>
+{
+ static String convert(R C::*p) {
+ if(!p)
+ return "NULL";
+ else
+ return detail::rawMemoryToString(p);
+ }
+};
+#endif // _MSC_VER
+
+template <typename T>
+String toString(const T& value) {
+ return StringMaker<T>::convert(value);
+}
+
+String toString(const char* in);
+String toString(bool in);
+String toString(float in);
+String toString(double in);
+String toString(double long in);
+
+String toString(char in);
+String toString(char unsigned in);
+String toString(int short in);
+String toString(int short unsigned in);
+String toString(int in);
+String toString(int unsigned in);
+String toString(int long in);
+String toString(int long unsigned in);
+
+#ifdef DOCTEST_CONFIG_WITH_LONG_LONG
+String toString(int long long in);
+String toString(int long long unsigned in);
+#endif // DOCTEST_CONFIG_WITH_LONG_LONG
+
+class Approx
+{
+public:
+ explicit Approx(double value);
+
+ Approx(Approx const& other)
+ : m_epsilon(other.m_epsilon)
+ , m_scale(other.m_scale)
+ , m_value(other.m_value) {}
+
+ Approx operator()(double value) {
+ Approx approx(value);
+ approx.epsilon(m_epsilon);
+ approx.scale(m_scale);
+ return approx;
+ }
+
+ friend bool operator==(double lhs, Approx const& rhs);
+ 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); }
+
+ Approx& epsilon(double newEpsilon) {
+ m_epsilon = newEpsilon;
+ return *this;
+ }
+
+ Approx& scale(double newScale) {
+ m_scale = newScale;
+ return *this;
+ }
+
+ String toString() const;
+
+private:
+ double m_epsilon;
+ double m_scale;
+ double m_value;
+};
+
+template <>
+inline String toString<Approx>(Approx const& value) {
+ return value.toString();
+}
+
+#if !defined(DOCTEST_CONFIG_DISABLE)
+
+namespace detail
+{
+ // the function type this library works with
+ typedef void (*funcType)(void);
+
+// not for anything below Visual Studio 2005 (VC++6 has no SFINAE - not sure about VS 2003)
+#if !defined(_MSC_VER) || _MSC_VER >= 1400
+ // clang-format off
+ template<class T> struct decay_array { typedef T type; };
+ template<class T, unsigned N> struct decay_array<T[N]> { typedef T* type; };
+ template<class T> struct decay_array<T[]> { typedef T* type; };
+
+ template<class T> struct not_char_pointer { enum { value = true }; };
+ template<> struct not_char_pointer<char*> { enum { value = false }; };
+ template<> struct not_char_pointer<const char*> { enum { value = false }; };
+
+ template<class T> struct can_use_op : not_char_pointer<typename decay_array<T>::type> {};
+
+ template<bool, class = void> struct enable_if {};
+ template<class T> struct enable_if<true, T> { typedef T type; };
+// clang-format on
+#endif // _MSC_VER
+
+ struct TestFailureException
+ {};
+
+ void checkIfShouldThrow(const char* assert_name);
+ void throwException();
+ bool always_false();
+ void* getNullPtr();
+
+ // a struct defining a registered test callback
+ struct TestData
+ {
+ // not used for determining uniqueness
+ const char* m_suite; // the test suite in which the test was added
+ const char* m_name; // name of the test function
+ funcType m_f; // a function pointer to the test function
+
+ // fields by which uniqueness of test cases shall be determined
+ const char* m_file; // the file in which the test was registered
+ unsigned m_line; // the line where the test was registered
+
+ TestData(const char* suite, const char* name, funcType f, const char* file, int line)
+ : m_suite(suite)
+ , m_name(name)
+ , m_f(f)
+ , m_file(file)
+ , m_line(line) {}
+
+ bool operator==(const TestData& other) const;
+ };
+
+ struct Subcase
+ {
+ const char* m_name;
+ const char* m_file;
+ int m_line;
+ bool m_entered;
+
+ Subcase(const char* name, const char* file, int line);
+ ~Subcase();
+ Subcase(const Subcase& other);
+ Subcase& operator=(const Subcase& other);
+
+ bool operator==(const Subcase& other) const;
+ operator bool() const { return m_entered; }
+ };
+
+ template <typename L, typename R>
+ String stringifyBinaryExpr(const L& lhs, const char* op, const R& rhs) {
+ return toString(lhs) + " " + op + " " + toString(rhs);
+ }
+
+ // TODO: think about this
+ //struct STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison;
+
+ struct Result
+ {
+ bool m_passed;
+ String m_decomposition;
+
+// to fix gcc 4.7 "-Winline" warnings
+#if defined(__GNUC__) && !defined(__clang__)
+ __attribute__((noinline))
+#endif
+ ~Result() {
+ }
+
+ Result(bool passed = false, const String& decomposition = String())
+ : m_passed(passed)
+ , m_decomposition(decomposition) {}
+
+// to fix gcc 4.7 "-Winline" warnings
+#if defined(__GNUC__) && !defined(__clang__)
+ __attribute__((noinline))
+#endif
+ Result&
+ operator=(const Result& other) {
+ m_passed = other.m_passed;
+ m_decomposition = other.m_decomposition;
+
+ return *this;
+ }
+
+ operator bool() { return !m_passed; }
+
+ void invert() { m_passed = !m_passed; }
+
+ // clang-format off
+ //template <typename R> STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator+(const R&);
+ //template <typename R> STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator-(const R&);
+ //template <typename R> STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator/(const R&);
+ //template <typename R> STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator*(const R&);
+ //template <typename R> STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator&&(const R&);
+ //template <typename R> STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator||(const R&);
+ //
+ //template <typename R> STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator==(const R&);
+ //template <typename R> STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator!=(const R&);
+ //template <typename R> STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator<(const R&);
+ //template <typename R> STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator<=(const R&);
+ //template <typename R> STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator>(const R&);
+ //template <typename R> STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator>=(const R&);
+ // clang-format on
+ };
+
+// clang-format off
+
+// for anything below Visual Studio 2005 (VC++6 has no SFINAE - not sure about VS 2003)
+#if defined(_MSC_VER) && _MSC_VER < 1400
+ template <typename L, typename R> bool eq (const L& lhs, const R& rhs) { return lhs == rhs; }
+ template <typename L, typename R> bool neq(const L& lhs, const R& rhs) { return lhs != rhs; }
+ template <typename L, typename R> bool lt (const L& lhs, const R& rhs) { return lhs < rhs; }
+ template <typename L, typename R> bool gt (const L& lhs, const R& rhs) { return lhs > rhs; }
+ template <typename L, typename R> bool lte(const L& lhs, const R& rhs) { return eq(lhs, rhs) != 0 ? lhs < rhs : true; }
+ template <typename L, typename R> bool gte(const L& lhs, const R& rhs) { return eq(lhs, rhs) != 0 ? lhs > rhs : true; }
+#else // _MSC_VER
+ template <typename L, typename R>
+ typename enable_if<can_use_op<L>::value || can_use_op<R>::value, bool>::type eq (const L& lhs, const R& rhs) { return lhs == rhs; }
+ template <typename L, typename R>
+ typename enable_if<can_use_op<L>::value || can_use_op<R>::value, bool>::type neq(const L& lhs, const R& rhs) { return lhs != rhs; }
+ template <typename L, typename R>
+ typename enable_if<can_use_op<L>::value || can_use_op<R>::value, bool>::type lt (const L& lhs, const R& rhs) { return lhs < rhs; }
+ template <typename L, typename R>
+ typename enable_if<can_use_op<L>::value || can_use_op<R>::value, bool>::type gt (const L& lhs, const R& rhs) { return lhs > rhs; }
+ template <typename L, typename R>
+ typename enable_if<can_use_op<L>::value || can_use_op<R>::value, bool>::type lte(const L& lhs, const R& rhs) { return neq(lhs, rhs) ? lhs < rhs : true; }
+ template <typename L, typename R>
+ typename enable_if<can_use_op<L>::value || can_use_op<R>::value, bool>::type gte(const L& lhs, const R& rhs) { return neq(lhs, rhs) ? lhs > rhs : true; }
+
+ inline bool eq (const char* lhs, const char* rhs) { return String(lhs) == String(rhs); }
+ inline bool neq(const char* lhs, const char* rhs) { return String(lhs) != String(rhs); }
+ inline bool lt (const char* lhs, const char* rhs) { return String(lhs) < String(rhs); }
+ inline bool gt (const char* lhs, const char* rhs) { return String(lhs) > String(rhs); }
+ inline bool lte(const char* lhs, const char* rhs) { return String(lhs) <= String(rhs); }
+ inline bool gte(const char* lhs, const char* rhs) { return String(lhs) >= String(rhs); }
+#endif // _MSC_VER
+
+ // clang-format on
+
+ template <typename L>
+ struct Expression_lhs
+ {
+ L lhs;
+
+ Expression_lhs(L in)
+ : lhs(in) {}
+
+ Expression_lhs(const Expression_lhs& other)
+ : lhs(other.lhs) {}
+
+ operator Result() { return Result(!!lhs, toString(lhs)); }
+
+ // clang-format off
+ template <typename R> Result operator==(const R& rhs) { return Result(eq (lhs, rhs), stringifyBinaryExpr(lhs, "==", rhs)); }
+ template <typename R> Result operator!=(const R& rhs) { return Result(neq(lhs, rhs), stringifyBinaryExpr(lhs, "!=", rhs)); }
+ template <typename R> Result operator< (const R& rhs) { return Result(lt (lhs, rhs), stringifyBinaryExpr(lhs, "<" , rhs)); }
+ template <typename R> Result operator<=(const R& rhs) { return Result(lte(lhs, rhs), stringifyBinaryExpr(lhs, "<=", rhs)); }
+ template <typename R> Result operator> (const R& rhs) { return Result(gt (lhs, rhs), stringifyBinaryExpr(lhs, ">" , rhs)); }
+ template <typename R> Result operator>=(const R& rhs) { return Result(gte(lhs, rhs), stringifyBinaryExpr(lhs, ">=", rhs)); }
+ // clang-format on
+ };
+
+ struct ExpressionDecomposer
+ {
+ template <typename L>
+ Expression_lhs<const L&> operator<<(const L& operand) {
+ return Expression_lhs<const L&>(operand);
+ }
+ };
+
+ // forward declarations of functions used by the macros
+ int regTest(void (*f)(void), unsigned line, const char* file, const char* name);
+ int setTestSuiteName(const char* name);
+
+ void addFailedAssert(const char* assert_name);
+
+ void logTestStart(const char* name, const char* file, unsigned line);
+ void logTestEnd();
+
+ void logTestCrashed();
+
+ void logAssert(bool passed, const char* decomposition, bool threw, const char* expr,
+ const char* assert_name, const char* file, int line);
+
+ void logAssertThrows(bool threw, const char* expr, const char* assert_name, const char* file,
+ int line);
+
+ void logAssertThrowsAs(bool threw, bool threw_as, const char* as, const char* expr,
+ const char* assert_name, const char* file, int line);
+
+ void logAssertNothrow(bool threw, const char* expr, const char* assert_name, const char* file,
+ int line);
+
+ bool isDebuggerActive();
+ void writeToDebugConsole(const String&);
+
+ struct TestAccessibleContextState
+ {
+ bool success; // include successful assertions in output
+ bool no_throw; // to skip exceptions-related assertion macros
+ bool no_breaks; // to not break into the debugger
+ const TestData* currentTest;
+ bool hasLoggedCurrentTestStart;
+ int numAssertionsForCurrentTestcase;
+ };
+
+ struct ContextState;
+
+ TestAccessibleContextState* getTestsContextState();
+} // namespace detail
+
+#endif // DOCTEST_CONFIG_DISABLE
+
+class Context
+{
+#if !defined(DOCTEST_CONFIG_DISABLE)
+ detail::ContextState* p;
+
+ void parseArgs(int argc, const char* const* argv, bool withDefaults = false);
+
+#endif // DOCTEST_CONFIG_DISABLE
+
+public:
+ Context(int argc, const char* const* argv);
+
+// to fix gcc 4.7 "-Winline" warnings
+#if defined(__GNUC__) && !defined(__clang__)
+ __attribute__((noinline))
+#endif
+ ~Context();
+
+ void addFilter(const char* filter, const char* value);
+ void setOption(const char* option, int value);
+ void setOption(const char* option, const char* value);
+
+ bool shouldExit();
+
+ int run();
+};
+
+} // namespace doctest
+
+// if registering is not disabled
+#if !defined(DOCTEST_CONFIG_DISABLE)
+
+// registers the test by initializing a dummy var with a function
+#if defined(__GNUC__) && !defined(__clang__)
+#define DOCTEST_REGISTER_FUNCTION(f, name) \
+ static int DOCTEST_ANONYMOUS(DOCTEST_AUTOGEN_VAR_) __attribute__((unused)) = \
+ doctest::detail::regTest(f, __LINE__, __FILE__, name);
+#elif defined(__clang__)
+#define DOCTEST_REGISTER_FUNCTION(f, name) \
+ _Pragma("clang diagnostic push") \
+ _Pragma("clang diagnostic ignored \"-Wglobal-constructors\"") static int \
+ DOCTEST_ANONYMOUS(DOCTEST_AUTOGEN_VAR_) = \
+ doctest::detail::regTest(f, __LINE__, __FILE__, name); \
+ _Pragma("clang diagnostic pop")
+#else // MSVC
+#define DOCTEST_REGISTER_FUNCTION(f, name) \
+ static int DOCTEST_ANONYMOUS(DOCTEST_AUTOGEN_VAR_) = \
+ doctest::detail::regTest(f, __LINE__, __FILE__, name);
+#endif // MSVC
+
+#define DOCTEST_IMPLEMENT_FIXTURE(der, base, func, name) \
+ namespace \
+ { \
+ struct der : base \
+ { void f(); }; \
+ static void func() { \
+ der v; \
+ v.f(); \
+ } \
+ DOCTEST_REGISTER_FUNCTION(func, name) \
+ } \
+ inline void der::f()
+
+#define DOCTEST_CREATE_AND_REGISTER_FUNCTION(f, name) \
+ static void f(); \
+ DOCTEST_REGISTER_FUNCTION(f, name) \
+ inline void f()
+
+// for registering tests
+#define DOCTEST_TEST_CASE(name) \
+ DOCTEST_CREATE_AND_REGISTER_FUNCTION(DOCTEST_ANONYMOUS(DOCTEST_AUTOGEN_FUNC_), name)
+
+// for registering tests with a fixture
+#define DOCTEST_TEST_CASE_FIXTURE(c, name) \
+ DOCTEST_IMPLEMENT_FIXTURE(DOCTEST_ANONYMOUS(DOCTEST_AUTOGEN_CLASS_), c, \
+ DOCTEST_ANONYMOUS(DOCTEST_AUTOGEN_FUNC_), name)
+
+// for subcases
+#if defined(__GNUC__)
+#define DOCTEST_SUBCASE(name) \
+ if(const doctest::detail::Subcase & DOCTEST_ANONYMOUS(DOCTEST_AUTOGEN_SUBCASE_) \
+ __attribute__((unused)) = \
+ doctest::detail::Subcase(name, __FILE__, __LINE__))
+#else // __GNUC__
+#define DOCTEST_SUBCASE(name) \
+ if(const doctest::detail::Subcase & DOCTEST_ANONYMOUS(DOCTEST_AUTOGEN_SUBCASE_) = \
+ doctest::detail::Subcase(name, __FILE__, __LINE__))
+#endif // __GNUC__
+
+// for starting a testsuite block
+#if defined(__GNUC__) && !defined(__clang__)
+#define DOCTEST_TEST_SUITE(name) \
+ static int DOCTEST_ANONYMOUS(DOCTEST_AUTOGEN_VAR_) __attribute__((unused)) = \
+ doctest::detail::setTestSuiteName(name); \
+ void DOCTEST_ANONYMOUS(DOCTEST_AUTOGEN_FOR_SEMICOLON_)()
+#elif defined(__clang__)
+#define DOCTEST_TEST_SUITE(name) \
+ _Pragma("clang diagnostic push") \
+ _Pragma("clang diagnostic ignored \"-Wglobal-constructors\"") static int \
+ DOCTEST_ANONYMOUS(DOCTEST_AUTOGEN_VAR_) = \
+ doctest::detail::setTestSuiteName(name); \
+ _Pragma("clang diagnostic pop") void DOCTEST_ANONYMOUS(DOCTEST_AUTOGEN_FOR_SEMICOLON_)()
+#else // MSVC
+#define DOCTEST_TEST_SUITE(name) \
+ static int DOCTEST_ANONYMOUS(DOCTEST_AUTOGEN_VAR_) = doctest::detail::setTestSuiteName(name); \
+ void DOCTEST_ANONYMOUS(DOCTEST_AUTOGEN_FOR_SEMICOLON_)()
+#endif // MSVC
+
+// for ending a testsuite block
+#if defined(__GNUC__) && !defined(__clang__)
+#define DOCTEST_TEST_SUITE_END \
+ static int DOCTEST_ANONYMOUS(DOCTEST_AUTOGEN_VAR_) __attribute__((unused)) = \
+ doctest::detail::setTestSuiteName(""); \
+ void DOCTEST_ANONYMOUS(DOCTEST_AUTOGEN_TESTSUITE_END_)
+#elif defined(__clang__)
+#define DOCTEST_TEST_SUITE_END \
+ _Pragma("clang diagnostic push") \
+ _Pragma("clang diagnostic ignored \"-Wglobal-constructors\"") static int \
+ DOCTEST_ANONYMOUS(DOCTEST_AUTOGEN_VAR_) = \
+ doctest::detail::setTestSuiteName(""); \
+ _Pragma("clang diagnostic pop") void DOCTEST_ANONYMOUS(DOCTEST_AUTOGEN_TESTSUITE_END_)
+#else // MSVC
+#define DOCTEST_TEST_SUITE_END \
+ static int DOCTEST_ANONYMOUS(DOCTEST_AUTOGEN_VAR_) = doctest::detail::setTestSuiteName(""); \
+ void DOCTEST_ANONYMOUS(DOCTEST_AUTOGEN_TESTSUITE_END_)
+#endif // MSVC
+
+#define DOCTEST_LOG_START() \
+ do { \
+ if(!DOCTEST_GCS()->hasLoggedCurrentTestStart) { \
+ doctest::detail::logTestStart(DOCTEST_GCS()->currentTest->m_name, \
+ DOCTEST_GCS()->currentTest->m_file, \
+ DOCTEST_GCS()->currentTest->m_line); \
+ DOCTEST_GCS()->hasLoggedCurrentTestStart = true; \
+ } \
+ } while(doctest::detail::always_false())
+
+#define DOCTEST_ASSERT_IMPLEMENT(expr, assert_name, false_invert_op) \
+ doctest::detail::Result res; \
+ bool threw = false; \
+ try { \
+ res = doctest::detail::ExpressionDecomposer() << expr; \
+ } catch(...) { threw = true; } \
+ false_invert_op; \
+ if(res || DOCTEST_GCS()->success) { \
+ DOCTEST_LOG_START(); \
+ doctest::detail::logAssert(res.m_passed, res.m_decomposition.c_str(), threw, #expr, \
+ assert_name, __FILE__, __LINE__); \
+ } \
+ DOCTEST_GCS()->numAssertionsForCurrentTestcase++; \
+ if(res) { \
+ doctest::detail::addFailedAssert(assert_name); \
+ DOCTEST_BREAK_INTO_DEBUGGER(); \
+ doctest::detail::checkIfShouldThrow(assert_name); \
+ }
+
+#if defined(__clang__)
+#define DOCTEST_ASSERT_PROXY(expr, assert_name, false_invert_op) \
+ do { \
+ _Pragma("clang diagnostic push") \
+ _Pragma("clang diagnostic ignored \"-Woverloaded-shift-op-parentheses\"") \
+ DOCTEST_ASSERT_IMPLEMENT(expr, assert_name, false_invert_op) \
+ _Pragma("clang diagnostic pop") \
+ } while(doctest::detail::always_false())
+#else // __clang__
+#define DOCTEST_ASSERT_PROXY(expr, assert_name, false_invert_op) \
+ do { \
+ DOCTEST_ASSERT_IMPLEMENT(expr, assert_name, false_invert_op) \
+ } while(doctest::detail::always_false())
+#endif // __clang__
+
+#define DOCTEST_WARN(expr) DOCTEST_ASSERT_PROXY(expr, "WARN", ((void)0))
+#define DOCTEST_CHECK(expr) DOCTEST_ASSERT_PROXY(expr, "CHECK", ((void)0))
+#define DOCTEST_REQUIRE(expr) DOCTEST_ASSERT_PROXY(expr, "REQUIRE", ((void)0))
+
+#define DOCTEST_WARN_FALSE(expr) DOCTEST_ASSERT_PROXY(expr, "WARN_FALSE", res.invert())
+#define DOCTEST_CHECK_FALSE(expr) DOCTEST_ASSERT_PROXY(expr, "CHECK_FALSE", res.invert())
+#define DOCTEST_REQUIRE_FALSE(expr) DOCTEST_ASSERT_PROXY(expr, "REQUIRE_FALSE", res.invert())
+
+#define DOCTEST_ASSERT_THROWS(expr, assert_name) \
+ do { \
+ if(!DOCTEST_GCS()->no_throw) { \
+ bool threw = false; \
+ try { \
+ expr; \
+ } catch(...) { threw = true; } \
+ if(!threw || DOCTEST_GCS()->success) { \
+ DOCTEST_LOG_START(); \
+ doctest::detail::logAssertThrows(threw, #expr, assert_name, __FILE__, __LINE__); \
+ } \
+ DOCTEST_GCS()->numAssertionsForCurrentTestcase++; \
+ if(!threw) { \
+ doctest::detail::addFailedAssert(assert_name); \
+ DOCTEST_BREAK_INTO_DEBUGGER(); \
+ doctest::detail::checkIfShouldThrow(assert_name); \
+ } \
+ } \
+ } while(doctest::detail::always_false())
+
+#define DOCTEST_ASSERT_THROWS_AS(expr, as, assert_name) \
+ do { \
+ if(!DOCTEST_GCS()->no_throw) { \
+ bool threw = false; \
+ bool threw_as = false; \
+ try { \
+ expr; \
+ } catch(as) { \
+ threw = true; \
+ threw_as = true; \
+ } catch(...) { threw = true; } \
+ if(!threw_as || DOCTEST_GCS()->success) { \
+ DOCTEST_LOG_START(); \
+ doctest::detail::logAssertThrowsAs(threw, threw_as, #as, #expr, assert_name, \
+ __FILE__, __LINE__); \
+ } \
+ DOCTEST_GCS()->numAssertionsForCurrentTestcase++; \
+ if(!threw_as) { \
+ doctest::detail::addFailedAssert(assert_name); \
+ DOCTEST_BREAK_INTO_DEBUGGER(); \
+ doctest::detail::checkIfShouldThrow(assert_name); \
+ } \
+ } \
+ } while(doctest::detail::always_false())
+
+#define DOCTEST_ASSERT_NOTHROW(expr, assert_name) \
+ do { \
+ if(!DOCTEST_GCS()->no_throw) { \
+ bool threw = false; \
+ try { \
+ expr; \
+ } catch(...) { threw = true; } \
+ if(threw || DOCTEST_GCS()->success) { \
+ DOCTEST_LOG_START(); \
+ doctest::detail::logAssertNothrow(threw, #expr, assert_name, __FILE__, __LINE__); \
+ } \
+ DOCTEST_GCS()->numAssertionsForCurrentTestcase++; \
+ if(threw) { \
+ doctest::detail::addFailedAssert(assert_name); \
+ DOCTEST_BREAK_INTO_DEBUGGER(); \
+ doctest::detail::checkIfShouldThrow(assert_name); \
+ } \
+ } \
+ } while(doctest::detail::always_false())
+
+#define DOCTEST_WARN_THROWS(expr) DOCTEST_ASSERT_THROWS(expr, "WARN_THROWS")
+#define DOCTEST_CHECK_THROWS(expr) DOCTEST_ASSERT_THROWS(expr, "CHECK_THROWS")
+#define DOCTEST_REQUIRE_THROWS(expr) DOCTEST_ASSERT_THROWS(expr, "REQUIRE_THROWS")
+
+#define DOCTEST_WARN_THROWS_AS(expr, ex) DOCTEST_ASSERT_THROWS_AS(expr, ex, "WARN_THROWS_AS")
+#define DOCTEST_CHECK_THROWS_AS(expr, ex) DOCTEST_ASSERT_THROWS_AS(expr, ex, "CHECK_THROWS_AS")
+#define DOCTEST_REQUIRE_THROWS_AS(expr, ex) DOCTEST_ASSERT_THROWS_AS(expr, ex, "REQUIRE_THROWS_AS")
+
+#define DOCTEST_WARN_NOTHROW(expr) DOCTEST_ASSERT_NOTHROW(expr, "WARN_NOTHROW")
+#define DOCTEST_CHECK_NOTHROW(expr) DOCTEST_ASSERT_NOTHROW(expr, "CHECK_NOTHROW")
+#define DOCTEST_REQUIRE_NOTHROW(expr) DOCTEST_ASSERT_NOTHROW(expr, "REQUIRE_NOTHROW")
+
+// =================================================================================================
+// == WHAT FOLLOWS IS VERSIONS OF THE MACROS THAT DO NOT DO ANY REGISTERING! ==
+// == THIS CAN BE ENABLED BY DEFINING DOCTEST_CONFIG_DISABLE GLOBALLY! ==
+// =================================================================================================
+#else // DOCTEST_CONFIG_DISABLE
+
+#define DOCTEST_IMPLEMENT_FIXTURE(der, base, func, name) \
+ namespace \
+ { \
+ template <typename T> \
+ struct der : base \
+ { void f(); }; \
+ } \
+ template <typename T> \
+ inline void der<T>::f()
+
+#define DOCTEST_CREATE_AND_REGISTER_FUNCTION(f, name) \
+ template <typename T> \
+ static inline void f()
+
+// for registering tests
+#define DOCTEST_TEST_CASE(name) \
+ DOCTEST_CREATE_AND_REGISTER_FUNCTION(DOCTEST_ANONYMOUS(DOCTEST_AUTOGEN_FUNC_), name)
+
+// for registering tests with a fixture
+#define DOCTEST_TEST_CASE_FIXTURE(x, name) \
+ DOCTEST_IMPLEMENT_FIXTURE(DOCTEST_ANONYMOUS(DOCTEST_AUTOGEN_CLASS_), x, \
+ DOCTEST_ANONYMOUS(DOCTEST_AUTOGEN_FUNC_), name)
+
+// for subcases
+#define DOCTEST_SUBCASE(name)
+
+// for starting a testsuite block
+#define DOCTEST_TEST_SUITE(name) void DOCTEST_ANONYMOUS(DOCTEST_AUTOGEN_FOR_SEMICOLON_)()
+
+// for ending a testsuite block
+#define DOCTEST_TEST_SUITE_END void DOCTEST_ANONYMOUS(DOCTEST_AUTOGEN_TESTSUITE_END_)
+
+#define DOCTEST_WARN(expr) ((void)0)
+#define DOCTEST_WARN_FALSE(expr) ((void)0)
+#define DOCTEST_WARN_THROWS(expr) ((void)0)
+#define DOCTEST_WARN_THROWS_AS(expr, ex) ((void)0)
+#define DOCTEST_WARN_NOTHROW(expr) ((void)0)
+#define DOCTEST_CHECK(expr) ((void)0)
+#define DOCTEST_CHECK_FALSE(expr) ((void)0)
+#define DOCTEST_CHECK_THROWS(expr) ((void)0)
+#define DOCTEST_CHECK_THROWS_AS(expr, ex) ((void)0)
+#define DOCTEST_CHECK_NOTHROW(expr) ((void)0)
+#define DOCTEST_REQUIRE(expr) ((void)0)
+#define DOCTEST_REQUIRE_FALSE(expr) ((void)0)
+#define DOCTEST_REQUIRE_THROWS(expr) ((void)0)
+#define DOCTEST_REQUIRE_THROWS_AS(expr, ex) ((void)0)
+#define DOCTEST_REQUIRE_NOTHROW(expr) ((void)0)
+
+#endif // DOCTEST_CONFIG_DISABLE
+
+// BDD style macros
+#define DOCTEST_SCENARIO(name) TEST_CASE("Scenario: " name)
+#define DOCTEST_GIVEN(name) SUBCASE(" Given: " name)
+#define DOCTEST_WHEN(name) SUBCASE(" When: " name)
+#define DOCTEST_AND_WHEN(name) SUBCASE("And when: " name)
+#define DOCTEST_THEN(name) SUBCASE(" Then: " name)
+#define DOCTEST_AND_THEN(name) SUBCASE(" And: " name)
+
+// == SHORT VERSIONS OF THE MACROS
+#if !defined(DOCTEST_CONFIG_NO_SHORT_MACRO_NAMES)
+
+#define TEST_CASE DOCTEST_TEST_CASE
+#define TEST_CASE_FIXTURE DOCTEST_TEST_CASE_FIXTURE
+#define SUBCASE DOCTEST_SUBCASE
+#define TEST_SUITE DOCTEST_TEST_SUITE
+#define TEST_SUITE_END DOCTEST_TEST_SUITE_END
+#define WARN DOCTEST_WARN
+#define WARN_FALSE DOCTEST_WARN_FALSE
+#define WARN_THROWS DOCTEST_WARN_THROWS
+#define WARN_THROWS_AS DOCTEST_WARN_THROWS_AS
+#define WARN_NOTHROW DOCTEST_WARN_NOTHROW
+#define CHECK DOCTEST_CHECK
+#define CHECK_FALSE DOCTEST_CHECK_FALSE
+#define CHECK_THROWS DOCTEST_CHECK_THROWS
+#define CHECK_THROWS_AS DOCTEST_CHECK_THROWS_AS
+#define CHECK_NOTHROW DOCTEST_CHECK_NOTHROW
+#define REQUIRE DOCTEST_REQUIRE
+#define REQUIRE_FALSE DOCTEST_REQUIRE_FALSE
+#define REQUIRE_THROWS DOCTEST_REQUIRE_THROWS
+#define REQUIRE_THROWS_AS DOCTEST_REQUIRE_THROWS_AS
+#define REQUIRE_NOTHROW DOCTEST_REQUIRE_NOTHROW
+
+#define SCENARIO DOCTEST_SCENARIO
+#define GIVEN DOCTEST_GIVEN
+#define WHEN DOCTEST_WHEN
+#define AND_WHEN DOCTEST_AND_WHEN
+#define THEN DOCTEST_THEN
+#define AND_THEN DOCTEST_AND_THEN
+
+#endif // DOCTEST_CONFIG_NO_SHORT_MACRO_NAMES
+
+// this is here to clear the 'current test suite' for the current translation unit - at the top
+DOCTEST_TEST_SUITE_END();
+
+#endif // DOCTEST_LIBRARY_INCLUDED
+
+// =================================================================================================
+// == WHAT FOLLOWS IS THE IMPLEMENTATION OF THE TEST RUNNER ==
+// =================================================================================================
+#if(defined(DOCTEST_CONFIG_IMPLEMENT) || defined(DOCTEST_CONFIG_IMPLEMENT_WITH_MAIN))
+#ifndef DOCTEST_LIBRARY_IMPLEMENTATION
+#define DOCTEST_LIBRARY_IMPLEMENTATION
+
+// required includes - will go only in one translation unit!
+#include <ctime>
+#include <cmath>
+#include <new>
+#include <cstdio>
+#include <cstdlib>
+#include <cstring>
+#include <limits>
+#include <sstream>
+#include <iomanip>
+
+namespace doctest
+{
+namespace detail
+{
+ // not using std::strlen() because of valgrind errors when optimizations are turned on
+ // 'Invalid read of size 4' when the test suite len (with '\0') is not a multiple of 4
+ // for details see http://stackoverflow.com/questions/35671155
+ size_t my_strlen(const char* in) {
+ const char* temp = in;
+ while(*temp)
+ ++temp;
+ return temp - in;
+ }
+
+ template <typename T>
+ T my_max(const T& lhs, const T& rhs) {
+ return lhs > rhs ? lhs : rhs;
+ }
+
+ // case insensitive strcmp
+ int stricmp(char const* a, char const* b) {
+ for(;; a++, b++) {
+ int d = tolower(*a) - tolower(*b);
+ if(d != 0 || !*a)
+ return d;
+ }
+ }
+
+ template <typename T>
+ String fpToString(T value, int precision) {
+ std::ostringstream oss;
+ oss << std::setprecision(precision) << std::fixed << value;
+ std::string d = oss.str();
+ 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.c_str();
+ }
+
+ 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;
+ }
+ };
+
+ String rawMemoryToString(const void* object, unsigned size) {
+ // Reverse order for little endian architectures
+ int i = 0, end = static_cast<int>(size), inc = 1;
+ if(Endianness::which() == Endianness::Little) {
+ i = end - 1;
+ end = inc = -1;
+ }
+
+ unsigned char const* bytes = static_cast<unsigned char const*>(object);
+ std::ostringstream os;
+ os << "0x" << std::setfill('0') << std::hex;
+ for(; i != end; i += inc)
+ os << std::setw(2) << static_cast<unsigned>(bytes[i]);
+ return os.str().c_str();
+ }
+
+ std::ostream* createStream() { return new std::ostringstream(); }
+ String getStreamResult(std::ostream* in) {
+ return static_cast<std::ostringstream*>(in)->str().c_str();
+ }
+ void freeStream(std::ostream* in) { delete in; }
+
+#ifndef DOCTEST_CONFIG_DISABLE
+ template <class T>
+ class Vector
+ {
+ unsigned m_size;
+ unsigned m_capacity;
+ T* m_buffer;
+
+ public:
+ Vector();
+ Vector(unsigned num, const T& val = T());
+ Vector(const Vector& other);
+ ~Vector();
+ Vector& operator=(const Vector& other);
+
+ T* data() { return m_buffer; }
+ const T* data() const { return m_buffer; }
+ unsigned size() const { return m_size; }
+
+ T& operator[](unsigned index) { return m_buffer[index]; }
+ const T& operator[](unsigned index) const { return m_buffer[index]; }
+
+ void clear();
+ void pop_back();
+ void push_back(const T& item);
+ void resize(unsigned num, const T& val = T());
+ };
+
+ // the default Hash() implementation that the HashTable class uses - returns 0 - very naive
+ // specialize for better HashTable performance
+ template <typename T>
+ unsigned Hash(const T&) {
+ return 0;
+ }
+
+ template <class T>
+ class HashTable
+ {
+ Vector<Vector<T> > buckets;
+
+ public:
+ explicit HashTable(unsigned num_buckets)
+ : buckets(num_buckets) {}
+
+ bool has(const T& in) const {
+ const Vector<T>& bucket = buckets[Hash(in) % buckets.size()];
+ for(unsigned i = 0; i < bucket.size(); ++i)
+ if(bucket[i] == in)
+ return true;
+ return false;
+ }
+
+ void insert(const T& in) {
+ if(!has(in))
+ buckets[Hash(in) % buckets.size()].push_back(in);
+ }
+
+ void clear() {
+ for(unsigned i = 0; i < buckets.size(); ++i)
+ buckets[i].clear();
+ }
+
+ const Vector<Vector<T> >& getBuckets() const { return buckets; }
+ };
+
+ // this holds both parameters for the command line and runtime data for tests
+ struct ContextState : TestAccessibleContextState
+ {
+ // == parameters from the command line
+
+ detail::Vector<detail::Vector<String> > filters;
+
+ String order_by; // how tests should be ordered
+ unsigned rand_seed; // the seed for rand ordering
+
+ unsigned first; // the first (matching) test to be executed
+ unsigned last; // the last (matching) test to be executed
+
+ int abort_after; // stop tests after this many failed assertions
+ bool case_sensitive; // if filtering should be case sensitive
+ bool exit; // if the program should be exited after the tests are ran/whatever
+ bool no_overrides; // to disable overrides from code
+ bool no_exitcode; // if the framework should return 0 as the exitcode
+ bool no_run; // to not run the tests at all (can be done with an "*" exclude)
+ bool no_colors; // if output to the console should be colorized
+ bool no_path_in_filenames; // if the path to files should be removed from the output
+
+ bool help; // to print the help
+ bool version; // to print the version
+ bool count; // if only the count of matching tests is to be retreived
+ bool list_test_cases; // to list all tests matching the filters
+ bool list_test_suites; // to list all suites matching the filters
+ bool hash_table_histogram; // if the hash table should be printed as a histogram
+
+ // == data for the tests being ran
+
+ int numAssertions;
+ int numFailedAssertions;
+ int numFailedAssertionsForCurrentTestcase;
+
+ // stuff for subcases
+ HashTable<Subcase> subcasesPassed;
+ HashTable<int> subcasesEnteredLevels;
+ Vector<Subcase> subcasesStack;
+ int subcasesCurrentLevel;
+ bool subcasesHasSkipped;
+
+ void resetRunData() {
+ numAssertions = 0;
+ numFailedAssertions = 0;
+ }
+
+ ContextState()
+ : filters(6) // 6 different filters total
+ , subcasesPassed(100)
+ , subcasesEnteredLevels(100) {
+ resetRunData();
+ }
+ };
+
+ ContextState*& getContextState();
+#endif
+} // namespace detail
+
+String::String(const char* in) {
+ m_str = static_cast<char*>(malloc(detail::my_strlen(in) + 1));
+ strcpy(m_str, in);
+}
+
+String::String(const String& other)
+ : m_str(0) {
+ copy(other);
+}
+
+void String::copy(const String& other) {
+ if(m_str)
+ free(m_str);
+ m_str = 0;
+
+ if(other.m_str) {
+ m_str = static_cast<char*>(malloc(detail::my_strlen(other.m_str) + 1));
+ strcpy(m_str, other.m_str);
+ }
+}
+
+String::~String() {
+ if(m_str)
+ free(m_str);
+}
+
+String& String::operator=(const String& other) {
+ if(this != &other)
+ copy(other);
+ return *this;
+}
+
+String String::operator+(const String& other) const { return String(m_str) += other; }
+
+String& String::operator+=(const String& other) {
+ using namespace detail;
+ if(m_str == 0) {
+ copy(other);
+ } else if(other.m_str != 0) {
+ char* newStr = static_cast<char*>(malloc(my_strlen(m_str) + my_strlen(other.m_str) + 1));
+ strcpy(newStr, m_str);
+ strcpy(newStr + my_strlen(m_str), other.m_str);
+ free(m_str);
+ m_str = newStr;
+ }
+ return *this;
+}
+
+unsigned String::size() const { return m_str ? detail::my_strlen(m_str) : 0; }
+unsigned String::length() const { return size(); }
+
+int String::compare(const char* other, bool no_case) const {
+ if(no_case)
+ return detail::stricmp(m_str, other);
+ return strcmp(m_str, other);
+}
+
+int String::compare(const String& other, bool no_case) const {
+ if(no_case)
+ return detail::stricmp(m_str, other.m_str);
+ return strcmp(m_str, other.m_str);
+}
+
+std::ostream& operator<<(std::ostream& stream, const String& in) {
+ stream << in.c_str();
+ return stream;
+}
+
+Approx::Approx(double value)
+ : m_epsilon(static_cast<double>(std::numeric_limits<float>::epsilon()) * 100)
+ , m_scale(1.0)
+ , m_value(value) {}
+
+bool operator==(double lhs, Approx const& rhs) {
+ // Thanks to Richard Harris for his help refining this formula
+ return fabs(lhs - rhs.m_value) <
+ rhs.m_epsilon * (rhs.m_scale + detail::my_max(fabs(lhs), fabs(rhs.m_value)));
+}
+
+String Approx::toString() const { return String("Approx( ") + doctest::toString(m_value) + " )"; }
+
+String toString(const char* in) { return String("\"") + (in ? in : "{null string}") + "\""; }
+String toString(bool in) { return in ? "true" : "false"; }
+String toString(float in) { return detail::fpToString(in, 5) + "f"; }
+String toString(double in) { return detail::fpToString(in, 10); }
+String toString(double long in) { return detail::fpToString(in, 15); }
+
+String toString(char in) {
+ char buf[64];
+ if(in < ' ')
+ sprintf(buf, "%d", in);
+ else
+ sprintf(buf, "%c", in);
+ return buf;
+}
+
+String toString(char unsigned in) {
+ char buf[64];
+ if(in < ' ')
+ sprintf(buf, "%ud", in);
+ else
+ sprintf(buf, "%c", in);
+ return buf;
+}
+
+String toString(int short in) {
+ char buf[64];
+ sprintf(buf, "%d", in);
+ return buf;
+}
+
+String toString(int short unsigned in) {
+ char buf[64];
+ sprintf(buf, "%u", in);
+ return buf;
+}
+
+String toString(int in) {
+ char buf[64];
+ sprintf(buf, "%d", in);
+ return buf;
+}
+
+String toString(int unsigned in) {
+ char buf[64];
+ sprintf(buf, "%u", in);
+ return buf;
+}
+
+String toString(int long in) {
+ char buf[64];
+ sprintf(buf, "%ld", in);
+ return buf;
+}
+
+String toString(int long unsigned in) {
+ char buf[64];
+ sprintf(buf, "%lu", in);
+ return buf;
+}
+
+#ifdef DOCTEST_CONFIG_WITH_LONG_LONG
+String toString(int long long in) {
+ char buf[64];
+ sprintf(buf, "%lld", in);
+ return buf;
+}
+String toString(int long long unsigned in) {
+ char buf[64];
+ sprintf(buf, "%llu", in);
+ return buf;
+}
+#endif // DOCTEST_CONFIG_WITH_LONG_LONG
+
+} // namespace doctest
+
+#if defined(DOCTEST_CONFIG_DISABLE)
+namespace doctest
+{
+Context::Context(int, const char* const*) {}
+Context::~Context() {}
+void Context::addFilter(const char*, const char*) {}
+void Context::setOption(const char*, int) {}
+void Context::setOption(const char*, const char*) {}
+bool Context::shouldExit() { return false; }
+int Context::run() { return 0; }
+} // namespace doctest
+#else // DOCTEST_CONFIG_DISABLE
+
+#if !defined(DOCTEST_CONFIG_COLORS_NONE)
+#if !defined(DOCTEST_CONFIG_COLORS_WINDOWS) && !defined(DOCTEST_CONFIG_COLORS_ANSI)
+#ifdef DOCTEST_PLATFORM_WINDOWS
+#define DOCTEST_CONFIG_COLORS_WINDOWS
+#else // linux
+#define DOCTEST_CONFIG_COLORS_ANSI
+#endif // platform
+#endif // DOCTEST_CONFIG_COLORS_WINDOWS && DOCTEST_CONFIG_COLORS_ANSI
+#endif // DOCTEST_CONFIG_COLORS_NONE
+
+#define DOCTEST_PRINTF_COLORED(buffer, color) \
+ do { \
+ if(buffer[0] != 0) { \
+ doctest::detail::Color col(color); \
+ printf("%s", buffer); \
+ } \
+ } while(doctest::detail::always_false())
+
+// the number of buckets used for the hash set
+#if !defined(DOCTEST_HASH_TABLE_NUM_BUCKETS)
+#define DOCTEST_HASH_TABLE_NUM_BUCKETS 1024
+#endif // DOCTEST_HASH_TABLE_NUM_BUCKETS
+
+// the buffer size used for snprintf() calls
+#if !defined(DOCTEST_SNPRINTF_BUFFER_LENGTH)
+#define DOCTEST_SNPRINTF_BUFFER_LENGTH 1024
+#endif // DOCTEST_SNPRINTF_BUFFER_LENGTH
+
+#if defined(_MSC_VER) || defined(__MINGW32__)
+extern "C" __declspec(dllimport) void __stdcall OutputDebugStringA(const char*);
+extern "C" __declspec(dllimport) int __stdcall IsDebuggerPresent();
+#endif // DOCTEST_PLATFORM_WINDOWS
+
+#ifdef DOCTEST_CONFIG_COLORS_ANSI
+#include <unistd.h>
+#endif // DOCTEST_CONFIG_COLORS_ANSI
+
+#ifdef DOCTEST_CONFIG_COLORS_WINDOWS
+
+// defines for a leaner windows.h
+#ifndef WIN32_MEAN_AND_LEAN
+#define WIN32_MEAN_AND_LEAN
+#endif // WIN32_MEAN_AND_LEAN
+#ifndef VC_EXTRA_LEAN
+#define VC_EXTRA_LEAN
+#endif // VC_EXTRA_LEAN
+#ifndef NOMINMAX
+#define NOMINMAX
+#endif // NOMINMAX
+
+// not sure what AfxWin.h is for - here I do what Catch does
+#ifdef __AFXDLL
+#include <AfxWin.h>
+#else
+#include <windows.h>
+#endif
+
+#endif // DOCTEST_CONFIG_COLORS_WINDOWS
+
+namespace doctest
+{
+namespace detail
+{
+ bool TestData::operator==(const TestData& other) const {
+ return m_line == other.m_line && strcmp(m_file, other.m_file) == 0;
+ }
+
+ void checkIfShouldThrow(const char* assert_name) {
+ if(strncmp(assert_name, "REQUIRE", 7) == 0)
+ throwException();
+
+ if(strncmp(assert_name, "CHECK", 5) == 0 && getContextState()->abort_after > 0) {
+ if(getContextState()->numFailedAssertions >= getContextState()->abort_after)
+ throwException();
+ }
+ }
+ void throwException() { throw doctest::detail::TestFailureException(); }
+ bool always_false() { return false; }
+ void* getNullPtr() { return 0; }
+
+ // lowers ascii letters
+ char tolower(const char c) { return ((c >= 'A' && c <= 'Z') ? static_cast<char>(c + 32) : c); }
+
+ // matching of a string against a wildcard mask (case sensitivity configurable) taken from
+ // http://www.emoticode.net/c/simple-wildcard-string-compare-globbing-function.html
+ int wildcmp(const char* str, const char* wild, bool caseSensitive) {
+ const char* cp = 0;
+ const char* mp = 0;
+
+ // rolled my own tolower() to not include more headers
+ while((*str) && (*wild != '*')) {
+ if((caseSensitive ? (*wild != *str) : (tolower(*wild) != tolower(*str))) &&
+ (*wild != '?')) {
+ return 0;
+ }
+ wild++;
+ str++;
+ }
+
+ while(*str) {
+ if(*wild == '*') {
+ if(!*++wild) {
+ return 1;
+ }
+ mp = wild;
+ cp = str + 1;
+ } else if((caseSensitive ? (*wild == *str) : (tolower(*wild) == tolower(*str))) ||
+ (*wild == '?')) {
+ wild++;
+ str++;
+ } else {
+ wild = mp;
+ str = cp++;
+ }
+ }
+
+ while(*wild == '*') {
+ wild++;
+ }
+ return !*wild;
+ }
+
+ // C string hash function (djb2) - taken from http://www.cse.yorku.ca/~oz/hash.html
+ unsigned hashStr(unsigned const char* str) {
+ unsigned long hash = 5381;
+ char c;
+
+ while((c = *str++))
+ hash = ((hash << 5) + hash) + c; // hash * 33 + c
+
+ return hash;
+ }
+
+ // checks if the name matches any of the filters (and can be configured what to do when empty)
+ int matchesAny(const char* name, Vector<String> filters, int matchEmpty, bool caseSensitive) {
+ if(filters.size() == 0 && matchEmpty)
+ return 1;
+ for(unsigned i = 0; i < filters.size(); ++i)
+ if(wildcmp(name, filters[i].c_str(), caseSensitive))
+ return 1;
+ return 0;
+ }
+
+ template <class T>
+ Vector<T>::Vector()
+ : m_size(0)
+ , m_capacity(0)
+ , m_buffer(0) {}
+
+ template <class T>
+ Vector<T>::Vector(unsigned num, const T& val)
+ : m_size(num)
+ , m_capacity(num)
+ , m_buffer(static_cast<T*>(malloc(sizeof(T) * m_capacity))) {
+ for(unsigned i = 0; i < m_size; ++i)
+ new(m_buffer + i) T(val);
+ }
+
+ template <class T>
+ Vector<T>::Vector(const Vector& other)
+ : m_size(other.m_size)
+ , m_capacity(other.m_capacity)
+ , m_buffer(static_cast<T*>(malloc(sizeof(T) * m_capacity))) {
+ for(unsigned i = 0; i < m_size; ++i)
+ new(m_buffer + i) T(other.m_buffer[i]);
+ }
+
+ template <class T>
+ Vector<T>::~Vector() {
+ for(unsigned i = 0; i < m_size; ++i)
+ (*(m_buffer + i)).~T();
+ free(m_buffer);
+ }
+
+ template <class T>
+ Vector<T>& Vector<T>::operator=(const Vector& other) {
+ if(this != &other) {
+ for(unsigned i = 0; i < m_size; ++i)
+ (*(m_buffer + i)).~T();
+ free(m_buffer);
+
+ m_size = other.m_size;
+ m_capacity = other.m_capacity;
+
+ m_buffer = static_cast<T*>(malloc(sizeof(T) * m_capacity));
+ for(unsigned i = 0; i < m_size; ++i)
+ new(m_buffer + i) T(other.m_buffer[i]);
+ }
+ return *this;
+ }
+
+ template <class T>
+ void Vector<T>::clear() {
+ for(unsigned i = 0; i < m_size; ++i)
+ (*(m_buffer + i)).~T();
+ m_size = 0;
+ }
+
+ template <class T>
+ void Vector<T>::pop_back() {
+ if(m_size > 0)
+ (*(m_buffer + --m_size)).~T();
+ }
+
+ template <class T>
+ void Vector<T>::push_back(const T& item) {
+ if(m_size < m_capacity) {
+ new(m_buffer + m_size++) T(item);
+ } else {
+ if(m_capacity == 0)
+ m_capacity = 5; // initial capacity
+ else
+ m_capacity *= 2; // capacity growth factor
+ T* temp = static_cast<T*>(malloc(sizeof(T) * m_capacity));
+ for(unsigned i = 0; i < m_size; ++i) {
+ new(temp + i) T(m_buffer[i]);
+ (*(m_buffer + i)).~T();
+ }
+ new(temp + m_size++) T(item);
+ free(m_buffer);
+ m_buffer = temp;
+ }
+ }
+
+ template <class T>
+ void Vector<T>::resize(unsigned num, const T& val) {
+ if(num < m_size) {
+ for(unsigned i = num; i < m_size; ++i)
+ (*(m_buffer + i)).~T();
+ m_size = num;
+ } else {
+ if(num > m_capacity) {
+ if(m_capacity == 0) {
+ m_buffer = static_cast<T*>(malloc(sizeof(T) * num));
+ } else {
+ T* temp = static_cast<T*>(malloc(sizeof(T) * num));
+ for(unsigned i = 0; i < m_size; ++i) {
+ new(temp + i) T(m_buffer[i]);
+ (*(m_buffer + i)).~T();
+ }
+ }
+
+ for(unsigned i = m_size; i < num; ++i)
+ new(m_buffer + i) T(val);
+
+ m_size = num;
+ m_capacity = num;
+ }
+ }
+ }
+
+ template <>
+ unsigned Hash(const Subcase& in) {
+ return hashStr(reinterpret_cast<unsigned const char*>(in.m_file)) ^ in.m_line;
+ }
+
+ template <>
+ unsigned Hash(const String& in) {
+ return hashStr(reinterpret_cast<unsigned const char*>(in.c_str()));
+ }
+
+ template <>
+ unsigned Hash(const int& in) {
+ return in;
+ }
+
+ // the current ContextState with which tests are being executed
+ ContextState*& getContextState() {
+ static ContextState* data = 0;
+ return data;
+ }
+
+ TestAccessibleContextState* getTestsContextState() { return getContextState(); }
+
+ Subcase::Subcase(const char* name, const char* file, int line)
+ : m_name(name)
+ , m_file(file)
+ , m_line(line)
+ , m_entered(false) {
+ ContextState* s = getContextState();
+
+ // if we have already completed it
+ if(s->subcasesPassed.has(*this))
+ return;
+
+ // if a Subcase on the same level has already been entered
+ if(s->subcasesEnteredLevels.has(s->subcasesCurrentLevel)) {
+ s->subcasesHasSkipped = true;
+ return;
+ }
+
+ s->subcasesStack.push_back(*this);
+ s->hasLoggedCurrentTestStart = false;
+ if(s->hasLoggedCurrentTestStart)
+ logTestEnd();
+
+ s->subcasesEnteredLevels.insert(s->subcasesCurrentLevel++);
+ m_entered = true;
+ }
+
+ Subcase::~Subcase() {
+ if(m_entered) {
+ ContextState* s = getContextState();
+
+ s->subcasesCurrentLevel--;
+ // only mark the subcase as passed if no subcases have been skipped
+ if(s->subcasesHasSkipped == false)
+ s->subcasesPassed.insert(*this);
+
+ s->subcasesStack.pop_back();
+ s->hasLoggedCurrentTestStart = false;
+ if(s->hasLoggedCurrentTestStart)
+ logTestEnd();
+ }
+ }
+
+ Subcase::Subcase(const Subcase& other)
+ : m_name(other.m_name)
+ , m_file(other.m_file)
+ , m_line(other.m_line)
+ , m_entered(other.m_entered) {}
+
+ Subcase& Subcase::operator=(const Subcase& other) {
+ m_name = other.m_name;
+ m_file = other.m_file;
+ m_line = other.m_line;
+ m_entered = other.m_entered;
+ return *this;
+ }
+
+ bool Subcase::operator==(const Subcase& other) const {
+ return m_line == other.m_line && strcmp(m_file, other.m_file) == 0;
+ }
+
+ unsigned Hash(const TestData& in) {
+ return hashStr(reinterpret_cast<unsigned const char*>(in.m_file)) ^ in.m_line;
+ }
+
+ // for sorting tests by file/line
+ int fileOrderComparator(const void* a, const void* b) {
+ const TestData* lhs = *static_cast<TestData* const*>(a);
+ const TestData* rhs = *static_cast<TestData* const*>(b);
+#ifdef _MSC_VER
+ // this is needed because MSVC gives different case for drive letters
+ // for __FILE__ when evaluated in a header and a source file
+ int res = stricmp(lhs->m_file, rhs->m_file);
+#else // _MSC_VER
+ int res = strcmp(lhs->m_file, rhs->m_file);
+#endif // _MSC_VER
+ if(res != 0)
+ return res;
+ return static_cast<int>(lhs->m_line - rhs->m_line);
+ }
+
+ // for sorting tests by suite/file/line
+ int suiteOrderComparator(const void* a, const void* b) {
+ const TestData* lhs = *static_cast<TestData* const*>(a);
+ const TestData* rhs = *static_cast<TestData* const*>(b);
+
+ int res = strcmp(lhs->m_suite, rhs->m_suite);
+ if(res != 0)
+ return res;
+ return fileOrderComparator(a, b);
+ }
+
+ // for sorting tests by name/suite/file/line
+ int nameOrderComparator(const void* a, const void* b) {
+ const TestData* lhs = *static_cast<TestData* const*>(a);
+ const TestData* rhs = *static_cast<TestData* const*>(b);
+
+ int res = strcmp(lhs->m_name, rhs->m_name);
+ if(res != 0)
+ return res;
+ return suiteOrderComparator(a, b);
+ }
+
+ // holds the current test suite
+ const char*& getCurrentTestSuite() {
+ static const char* data = 0;
+ return data;
+ }
+
+ // sets the current test suite
+ int setTestSuiteName(const char* name) {
+ getCurrentTestSuite() = name;
+ return 0;
+ }
+
+ // all the registered tests
+ HashTable<TestData>& getRegisteredTests() {
+ static HashTable<TestData> data(DOCTEST_HASH_TABLE_NUM_BUCKETS);
+ return data;
+ }
+
+ // used by the macros for registering tests
+ int regTest(funcType f, unsigned line, const char* file, const char* name) {
+ getRegisteredTests().insert(TestData(getCurrentTestSuite(), name, f, file, line));
+ return 0;
+ }
+
+ struct Color
+ {
+ 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
+ };
+ Color(Code code) { use(code); }
+ ~Color() { use(None); }
+
+ void use(Code code);
+
+ private:
+ Color(Color const& other);
+ };
+
+ void Color::use(Code
+#ifndef DOCTEST_CONFIG_COLORS_NONE
+ code
+#endif // DOCTEST_CONFIG_COLORS_NONE
+ ) {
+ ContextState* p = getContextState();
+ if(p->no_colors)
+ return;
+#ifdef DOCTEST_CONFIG_COLORS_ANSI
+ if(isatty(STDOUT_FILENO)) {
+ const char* col = "";
+ // clang-format off
+ switch(code) {
+ case Color::Red: col = "[0;31m"; break;
+ case Color::Green: col = "[0;32m"; break;
+ case Color::Blue: col = "[0:34m"; break;
+ case Color::Cyan: col = "[0;36m"; break;
+ case Color::Yellow: col = "[0;33m"; break;
+ case Color::Grey: col = "[1;30m"; break;
+ case Color::LightGrey: col = "[0;37m"; break;
+ case Color::BrightRed: col = "[1;31m"; break;
+ case Color::BrightGreen: col = "[1;32m"; break;
+ case Color::BrightWhite: col = "[1;37m"; break;
+ case Color::Bright: // invalid
+ case Color::None:
+ case Color::White:
+ default: col = "[0m";
+ }
+ // clang-format on
+ printf("\033%s", col);
+ }
+#endif // DOCTEST_CONFIG_COLORS_ANSI
+
+#ifdef DOCTEST_CONFIG_COLORS_WINDOWS
+ static HANDLE stdoutHandle(GetStdHandle(STD_OUTPUT_HANDLE));
+ static WORD originalForegroundAttributes;
+ static WORD originalBackgroundAttributes;
+ static bool attrsInitted = false;
+ if(!attrsInitted) {
+ attrsInitted = true;
+ 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);
+ }
+
+#define DOCTEST_SET_ATTR(x) SetConsoleTextAttribute(stdoutHandle, x | originalBackgroundAttributes)
+
+ // clang-format off
+ switch (code) {
+ case Color::White: DOCTEST_SET_ATTR(FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_BLUE); break;
+ case Color::Red: DOCTEST_SET_ATTR(FOREGROUND_RED); break;
+ case Color::Green: DOCTEST_SET_ATTR(FOREGROUND_GREEN); break;
+ case Color::Blue: DOCTEST_SET_ATTR(FOREGROUND_BLUE); break;
+ case Color::Cyan: DOCTEST_SET_ATTR(FOREGROUND_BLUE | FOREGROUND_GREEN); break;
+ case Color::Yellow: DOCTEST_SET_ATTR(FOREGROUND_RED | FOREGROUND_GREEN); break;
+ case Color::Grey: DOCTEST_SET_ATTR(0); break;
+ case Color::LightGrey: DOCTEST_SET_ATTR(FOREGROUND_INTENSITY); break;
+ case Color::BrightRed: DOCTEST_SET_ATTR(FOREGROUND_INTENSITY | FOREGROUND_RED); break;
+ case Color::BrightGreen: DOCTEST_SET_ATTR(FOREGROUND_INTENSITY | FOREGROUND_GREEN); break;
+ case Color::BrightWhite: DOCTEST_SET_ATTR(FOREGROUND_INTENSITY | FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_BLUE); break;
+ case Color::None:
+ case Color::Bright: // invalid
+ default: DOCTEST_SET_ATTR(originalForegroundAttributes);
+ }
+// clang-format on
+#undef DOCTEST_SET_ATTR
+#endif // DOCTEST_CONFIG_COLORS_WINDOWS
+ }
+
+ // this is needed because MSVC does not permit mixing 2 exception handling schemes in a function
+ int callTestFunc(funcType f) {
+ int res = EXIT_SUCCESS;
+ try {
+ f();
+ if(getContextState()->numFailedAssertionsForCurrentTestcase)
+ res = EXIT_FAILURE;
+ } catch(const TestFailureException&) { res = EXIT_FAILURE; } catch(...) {
+ DOCTEST_LOG_START();
+ logTestCrashed();
+ res = EXIT_FAILURE;
+ }
+ return res;
+ }
+
+ // depending on the current options this will remove the path of filenames
+ const char* fileForOutput(const char* file) {
+ if(getContextState()->no_path_in_filenames) {
+ const char* back = strrchr(file, '\\');
+ const char* forward = strrchr(file, '/');
+ if(back || forward) {
+ if(back > forward)
+ forward = back;
+ return forward + 1;
+ }
+ }
+ return file;
+ }
+
+#ifdef DOCTEST_PLATFORM_MAC
+#include <sys/types.h>
+#include <unistd.h>
+#include <sys/sysctl.h>
+ // 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, 0, 0) != 0) {
+ fprintf(stderr, "\n** Call to sysctl failed - unable to determine if debugger is "
+ "active **\n\n");
+ return false;
+ }
+ // We're being debugged if the P_TRACED flag is set.
+ return ((info.kp_proc.p_flag & P_TRACED) != 0);
+ }
+#elif defined(_MSC_VER) || defined(__MINGW32__)
+ bool isDebuggerActive() { return ::IsDebuggerPresent() != 0; }
+#else
+ bool isDebuggerActive() { return false; }
+#endif // Platform
+
+#ifdef DOCTEST_PLATFORM_WINDOWS
+ void myOutputDebugString(const String& text) { ::OutputDebugStringA(text.c_str()); }
+#else
+ // TODO: integration with XCode and other IDEs
+ void myOutputDebugString(const String&) {}
+#endif // Platform
+
+ const char* getSeparator() {
+ return "===============================================================================\n";
+ }
+
+ void printToDebugConsole(const String& text) {
+ if(isDebuggerActive())
+ myOutputDebugString(text.c_str());
+ }
+
+ void addFailedAssert(const char* assert_name) {
+ if(strncmp(assert_name, "WARN", 4) != 0) {
+ getContextState()->numFailedAssertionsForCurrentTestcase++;
+ getContextState()->numFailedAssertions++;
+ }
+ }
+
+ void logTestStart(const char* name, const char* file, unsigned line) {
+ const char* newLine = "\n";
+
+ char loc[DOCTEST_SNPRINTF_BUFFER_LENGTH];
+ DOCTEST_SNPRINTF(loc, DOCTEST_COUNTOF(loc), "%s(%d)\n", fileForOutput(file), line);
+
+ char msg[DOCTEST_SNPRINTF_BUFFER_LENGTH];
+ DOCTEST_SNPRINTF(msg, DOCTEST_COUNTOF(msg), "%s\n", name);
+
+ DOCTEST_PRINTF_COLORED(getSeparator(), Color::Yellow);
+ DOCTEST_PRINTF_COLORED(loc, Color::LightGrey);
+ DOCTEST_PRINTF_COLORED(msg, Color::None);
+
+ String subcaseStuff = "";
+ Vector<Subcase>& subcasesStack = getContextState()->subcasesStack;
+ String tabulation;
+ for(unsigned i = 0; i < subcasesStack.size(); ++i) {
+ tabulation += " ";
+ char subcase[DOCTEST_SNPRINTF_BUFFER_LENGTH];
+ DOCTEST_SNPRINTF(subcase, DOCTEST_COUNTOF(loc), "%s%s\n", tabulation.c_str(),
+ subcasesStack[i].m_name);
+ DOCTEST_PRINTF_COLORED(subcase, Color::None);
+ subcaseStuff += subcase;
+ }
+
+ DOCTEST_PRINTF_COLORED(newLine, Color::None);
+
+ printToDebugConsole(String(getSeparator()) + loc + msg + subcaseStuff.c_str() + newLine);
+ }
+
+ void logTestEnd() {}
+
+ void logTestCrashed() {
+ char msg[DOCTEST_SNPRINTF_BUFFER_LENGTH];
+
+ DOCTEST_SNPRINTF(msg, DOCTEST_COUNTOF(msg), " TEST CASE FAILED! (threw exception)\n\n");
+
+ DOCTEST_PRINTF_COLORED(msg, Color::Red);
+
+ printToDebugConsole(String(msg));
+ }
+
+ void logAssert(bool passed, const char* decomposition, bool threw, const char* expr,
+ const char* assert_name, const char* file, int line) {
+ char loc[DOCTEST_SNPRINTF_BUFFER_LENGTH];
+ DOCTEST_SNPRINTF(loc, DOCTEST_COUNTOF(loc), "%s(%d)", fileForOutput(file), line);
+
+ char msg[DOCTEST_SNPRINTF_BUFFER_LENGTH];
+ if(passed)
+ DOCTEST_SNPRINTF(msg, DOCTEST_COUNTOF(msg), " PASSED!\n");
+ else
+ DOCTEST_SNPRINTF(msg, DOCTEST_COUNTOF(msg), " FAILED! %s\n",
+ (threw ? "(threw exception)" : ""));
+
+ char info1[DOCTEST_SNPRINTF_BUFFER_LENGTH];
+ DOCTEST_SNPRINTF(info1, DOCTEST_COUNTOF(info1), " %s( %s )\n", assert_name, expr);
+
+ char info2[DOCTEST_SNPRINTF_BUFFER_LENGTH];
+ char info3[DOCTEST_SNPRINTF_BUFFER_LENGTH];
+ info2[0] = 0;
+ info3[0] = 0;
+ if(!threw) {
+ DOCTEST_SNPRINTF(info2, DOCTEST_COUNTOF(info2), "with expansion:\n");
+ DOCTEST_SNPRINTF(info3, DOCTEST_COUNTOF(info3), " %s( %s )\n", assert_name,
+ decomposition);
+ }
+
+ DOCTEST_PRINTF_COLORED(loc, Color::LightGrey);
+ DOCTEST_PRINTF_COLORED(msg, passed ? Color::BrightGreen : Color::Red);
+ DOCTEST_PRINTF_COLORED(info1, Color::Green);
+ DOCTEST_PRINTF_COLORED(info2, Color::None);
+ DOCTEST_PRINTF_COLORED(info3, Color::Green);
+ DOCTEST_PRINTF_COLORED("\n", Color::None);
+
+ printToDebugConsole(String(loc) + msg + info1 + info2 + info3 + "\n");
+ }
+
+ void logAssertThrows(bool threw, const char* expr, const char* assert_name, const char* file,
+ int line) {
+ char loc[DOCTEST_SNPRINTF_BUFFER_LENGTH];
+ DOCTEST_SNPRINTF(loc, DOCTEST_COUNTOF(loc), "%s(%d)", fileForOutput(file), line);
+
+ char msg[DOCTEST_SNPRINTF_BUFFER_LENGTH];
+ if(threw)
+ DOCTEST_SNPRINTF(msg, DOCTEST_COUNTOF(msg), " PASSED!\n");
+ else
+ DOCTEST_SNPRINTF(msg, DOCTEST_COUNTOF(msg), " FAILED!\n");
+
+ char info1[DOCTEST_SNPRINTF_BUFFER_LENGTH];
+ DOCTEST_SNPRINTF(info1, DOCTEST_COUNTOF(info1), " %s( %s )\n\n", assert_name, expr);
+
+ DOCTEST_PRINTF_COLORED(loc, Color::LightGrey);
+ DOCTEST_PRINTF_COLORED(msg, threw ? Color::BrightGreen : Color::Red);
+ DOCTEST_PRINTF_COLORED(info1, Color::Green);
+
+ printToDebugConsole(String(loc) + msg + info1);
+ }
+
+ void logAssertThrowsAs(bool threw, bool threw_as, const char* as, const char* expr,
+ const char* assert_name, const char* file, int line) {
+ char loc[DOCTEST_SNPRINTF_BUFFER_LENGTH];
+ DOCTEST_SNPRINTF(loc, DOCTEST_COUNTOF(loc), "%s(%d)", fileForOutput(file), line);
+
+ char msg[DOCTEST_SNPRINTF_BUFFER_LENGTH];
+ if(threw_as)
+ DOCTEST_SNPRINTF(msg, DOCTEST_COUNTOF(msg), " PASSED!\n");
+ else
+ DOCTEST_SNPRINTF(msg, DOCTEST_COUNTOF(msg), " FAILED! %s\n",
+ (threw ? "(threw something else)" : "(didn't throw at all)"));
+
+ char info1[DOCTEST_SNPRINTF_BUFFER_LENGTH];
+ DOCTEST_SNPRINTF(info1, DOCTEST_COUNTOF(info1), " %s( %s, %s )\n\n", assert_name, expr,
+ as);
+
+ DOCTEST_PRINTF_COLORED(loc, Color::LightGrey);
+ DOCTEST_PRINTF_COLORED(msg, threw_as ? Color::BrightGreen : Color::Red);
+ DOCTEST_PRINTF_COLORED(info1, Color::Green);
+
+ printToDebugConsole(String(loc) + msg + info1);
+ }
+
+ void logAssertNothrow(bool threw, const char* expr, const char* assert_name, const char* file,
+ int line) {
+ char loc[DOCTEST_SNPRINTF_BUFFER_LENGTH];
+ DOCTEST_SNPRINTF(loc, DOCTEST_COUNTOF(loc), "%s(%d)", fileForOutput(file), line);
+
+ char msg[DOCTEST_SNPRINTF_BUFFER_LENGTH];
+ if(!threw)
+ DOCTEST_SNPRINTF(msg, DOCTEST_COUNTOF(msg), " PASSED!\n");
+ else
+ DOCTEST_SNPRINTF(msg, DOCTEST_COUNTOF(msg), " FAILED!\n");
+
+ char info1[DOCTEST_SNPRINTF_BUFFER_LENGTH];
+ DOCTEST_SNPRINTF(info1, DOCTEST_COUNTOF(info1), " %s( %s )\n\n", assert_name, expr);
+
+ DOCTEST_PRINTF_COLORED(loc, Color::LightGrey);
+ DOCTEST_PRINTF_COLORED(msg, !threw ? Color::BrightGreen : Color::Red);
+ DOCTEST_PRINTF_COLORED(info1, Color::Green);
+
+ printToDebugConsole(String(loc) + msg + info1);
+ }
+
+ // the implementation of parseFlag()
+ bool parseFlagImpl(int argc, const char* const* argv, const char* pattern) {
+ for(int i = argc - 1; i >= 0; --i) {
+ const char* temp = strstr(argv[i], pattern);
+ if(temp && my_strlen(temp) == my_strlen(pattern)) {
+ // eliminate strings in which the chars before the option are not '-'
+ bool noBadCharsFound = true;
+ while(temp != argv[i]) {
+ if(*--temp != '-') {
+ noBadCharsFound = false;
+ break;
+ }
+ }
+ if(noBadCharsFound)
+ return true;
+ }
+ }
+ return false;
+ }
+
+ // locates a flag on the command line
+ bool parseFlag(int argc, const char* const* argv, const char* pattern) {
+#ifndef DOCTEST_CONFIG_NO_UNPREFIXED_OPTIONS
+ if(!parseFlagImpl(argc, argv, pattern))
+ return parseFlagImpl(argc, argv, pattern + 3); // 3 for "dt-"
+ return true;
+#else // DOCTEST_CONFIG_NO_UNPREFIXED_OPTIONS
+ return parseFlagImpl(argc, argv, pattern);
+#endif // DOCTEST_CONFIG_NO_UNPREFIXED_OPTIONS
+ }
+
+ // the implementation of parseOption()
+ bool parseOptionImpl(int argc, const char* const* argv, const char* pattern, String& res) {
+ for(int i = argc - 1; i >= 0; --i) {
+ const char* temp = strstr(argv[i], pattern);
+ if(temp) {
+ // eliminate matches in which the chars before the option are not '-'
+ bool noBadCharsFound = true;
+ const char* curr = argv[i];
+ while(curr != temp) {
+ if(*curr++ != '-') {
+ noBadCharsFound = false;
+ break;
+ }
+ }
+ if(noBadCharsFound) {
+ temp += my_strlen(pattern);
+ unsigned len = my_strlen(temp);
+ if(len) {
+ res = temp;
+ return true;
+ }
+ }
+ }
+ }
+ return false;
+ }
+
+ // parses an option and returns the string after the '=' character
+ bool parseOption(int argc, const char* const* argv, const char* pattern, String& res,
+ const String& defaultVal = String()) {
+ res = defaultVal;
+#ifndef DOCTEST_CONFIG_NO_UNPREFIXED_OPTIONS
+ if(!parseOptionImpl(argc, argv, pattern, res))
+ return parseOptionImpl(argc, argv, pattern + 3, res); // 3 for "dt-"
+ return true;
+#else // DOCTEST_CONFIG_NO_UNPREFIXED_OPTIONS
+ return parseOptionImpl(argc, argv, pattern, res);
+#endif // DOCTEST_CONFIG_NO_UNPREFIXED_OPTIONS
+ }
+
+ // parses a comma separated list of words after a pattern in one of the arguments in argv
+ bool parseCommaSepArgs(int argc, const char* const* argv, const char* pattern,
+ Vector<String>& res) {
+ String filtersString;
+ if(parseOption(argc, argv, pattern, filtersString)) {
+ // tokenize with "," as a separator
+ char* pch = strtok(filtersString.c_str(), ","); // modifies the string
+ while(pch != 0) {
+ if(my_strlen(pch))
+ res.push_back(pch);
+ pch = strtok(0, ","); // uses the strtok() internal state to go to the next token
+ }
+ return true;
+ }
+ return false;
+ }
+
+ enum optionType
+ {
+ option_bool,
+ option_int
+ };
+
+ // parses an int/bool option from the command line
+ bool parseIntOption(int argc, const char* const* argv, const char* pattern, optionType type,
+ int& res) {
+ String parsedValue;
+ if(parseOption(argc, argv, pattern, parsedValue)) {
+ if(type == 0) {
+ // boolean
+ const char positive[][5] = {"1", "true", "on", "yes"}; // 5 - strlen("true") + 1
+ const char negative[][6] = {"0", "false", "off", "no"}; // 6 - strlen("false") + 1
+
+ // if the value matches any of the positive/negative possibilities
+ for(unsigned i = 0; i < 4; i++) {
+ if(parsedValue.compare(positive[i], true) == 0) {
+ res = 1;
+ return true;
+ }
+ if(parsedValue.compare(negative[i], true) == 0) {
+ res = 0;
+ return true;
+ }
+ }
+ } else {
+ // integer
+ int theInt = atoi(parsedValue.c_str());
+ if(theInt != 0) {
+ res = theInt;
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
+ void printVersion() {
+ DOCTEST_PRINTF_COLORED("[doctest] ", Color::Cyan);
+ printf("doctest version is \"%s\"\n", DOCTEST_VERSION);
+ }
+
+ void printHelp() {
+ printVersion();
+ DOCTEST_PRINTF_COLORED("[doctest]\n", Color::Cyan);
+ DOCTEST_PRINTF_COLORED("[doctest] ", Color::Cyan);
+ printf("boolean values: \"1/on/yes/true\" or \"0/off/no/false\"\n");
+ DOCTEST_PRINTF_COLORED("[doctest] ", Color::Cyan);
+ printf("filter values: \"str1,str2,str3\" (comma separated strings)\n");
+ DOCTEST_PRINTF_COLORED("[doctest]\n", Color::Cyan);
+ DOCTEST_PRINTF_COLORED("[doctest] ", Color::Cyan);
+ printf("filters use wildcards for matching strings\n");
+ DOCTEST_PRINTF_COLORED("[doctest] ", Color::Cyan);
+ printf("something passes a filter if any of the strings in a filter matches\n");
+ DOCTEST_PRINTF_COLORED("[doctest]\n", Color::Cyan);
+ DOCTEST_PRINTF_COLORED("[doctest] ", Color::Cyan);
+ printf("ALL FLAGS, OPTIONS AND FILTERS ALSO AVAILABLE WITH A \"dt-\" PREFIX!!!\n");
+ DOCTEST_PRINTF_COLORED("[doctest]\n", Color::Cyan);
+ DOCTEST_PRINTF_COLORED("[doctest] ", Color::Cyan);
+ printf("Query flags - the program quits after them. Available:\n\n");
+ printf(" -?, --help, -h prints this message\n");
+ printf(" -v, --version prints the version\n");
+ printf(" -c, --count prints the number of matching tests\n");
+ printf(" -ltc, --list-test-cases lists all matching tests by name\n");
+ printf(" -lts, --list-test-suites lists all matching test suites\n\n");
+ //printf(" -hth, --hash-table-histogram undocumented\n");
+ // ==================================================================================== << 79
+ DOCTEST_PRINTF_COLORED("[doctest] ", Color::Cyan);
+ printf("The available <int>/<string> options/filters are:\n\n");
+ printf(" -tc, --test-case=<filters> filters tests by their name\n");
+ printf(" -tce, --test-case-exclude=<filters> filters OUT tests by their name\n");
+ printf(" -sf, --source-file=<filters> filters tests by their file\n");
+ printf(" -sfe, --source-file-exclude=<filters> filters OUT tests by their file\n");
+ printf(" -ts, --test-suite=<filters> filters tests by their test suite\n");
+ printf(" -tse, --test-suite-exclude=<filters> filters OUT tests by their test suite\n");
+ printf(" -ob, --order-by=<string> how the tests should be ordered\n");
+ printf(" <string> - by [file/suite/name/rand]\n");
+ printf(" -rs, --rand-seed=<int> seed for random ordering\n");
+ printf(" -f, --first=<int> the first test passing the filters to\n");
+ printf(" execute - for range-based execution\n");
+ printf(" -l, --last=<int> the last test passing the filters to\n");
+ printf(" execute - for range-based execution\n");
+ printf(" -aa, --abort-after=<int> stop after <int> failed assertions\n\n");
+ DOCTEST_PRINTF_COLORED("[doctest] ", Color::Cyan);
+ printf("Bool options - can be used like flags and true is assumed. Available:\n\n");
+ printf(" -s, --success=<bool> include successful assertions in output\n");
+ printf(" -cs, --case-sensitive=<bool> filters being treated as case sensitive\n");
+ printf(" -e, --exit=<bool> exits after the tests finish\n");
+ printf(" -no, --no-overrides=<bool> disables procedural overrides of options\n");
+ printf(" -nt, --no-throw=<bool> skips exceptions-related assert checks\n");
+ printf(" -ne, --no-exitcode=<bool> returns (or exits) always with success\n");
+ printf(" -nr, --no-run=<bool> skips all runtime doctest operations\n");
+ printf(" -nc, --no-colors=<bool> disables colors in output\n");
+ printf(" -nb, --no-breaks=<bool> disables breakpoints in debuggers\n");
+ printf(" -npf, --no-path-filenames=<bool> only filenames and no paths in output\n\n");
+ // ==================================================================================== << 79
+
+ DOCTEST_PRINTF_COLORED("[doctest] ", Color::Cyan);
+ printf("for more information visit the project documentation\n\n");
+ }
+} // namespace detail
+
+Context::Context(int argc, const char* const* argv)
+ : p(new detail::ContextState) {
+ using namespace detail;
+
+ parseArgs(argc, argv, true);
+
+ p->help = false;
+ p->version = false;
+ p->count = false;
+ p->list_test_cases = false;
+ p->list_test_suites = false;
+ p->hash_table_histogram = false;
+ if(parseFlag(argc, argv, "dt-help") || parseFlag(argc, argv, "dt-h") ||
+ parseFlag(argc, argv, "dt-?")) {
+ p->help = true;
+ p->exit = true;
+ }
+ if(parseFlag(argc, argv, "dt-version") || parseFlag(argc, argv, "dt-v")) {
+ p->version = true;
+ p->exit = true;
+ }
+ if(parseFlag(argc, argv, "dt-count") || parseFlag(argc, argv, "dt-c")) {
+ p->count = true;
+ p->exit = true;
+ }
+ if(parseFlag(argc, argv, "dt-list-test-cases") || parseFlag(argc, argv, "dt-ltc")) {
+ p->list_test_cases = true;
+ p->exit = true;
+ }
+ if(parseFlag(argc, argv, "dt-list-test-suites") || parseFlag(argc, argv, "dt-lts")) {
+ p->list_test_suites = true;
+ p->exit = true;
+ }
+ if(parseFlag(argc, argv, "dt-hash-table-histogram") || parseFlag(argc, argv, "dt-hth")) {
+ p->hash_table_histogram = true;
+ p->exit = true;
+ }
+}
+
+Context::~Context() { delete p; }
+
+// parses args
+void Context::parseArgs(int argc, const char* const* argv, bool withDefaults) {
+ using namespace detail;
+
+ // clang-format off
+ parseCommaSepArgs(argc, argv, "dt-source-file=", p->filters[0]);
+ parseCommaSepArgs(argc, argv, "dt-sf=", p->filters[0]);
+ parseCommaSepArgs(argc, argv, "dt-source-file-exclude=",p->filters[1]);
+ parseCommaSepArgs(argc, argv, "dt-sfe=", p->filters[1]);
+ parseCommaSepArgs(argc, argv, "dt-test-suite=", p->filters[2]);
+ parseCommaSepArgs(argc, argv, "dt-ts=", p->filters[2]);
+ parseCommaSepArgs(argc, argv, "dt-test-suite-exclude=", p->filters[3]);
+ parseCommaSepArgs(argc, argv, "dt-tse=", p->filters[3]);
+ parseCommaSepArgs(argc, argv, "dt-test-case=", p->filters[4]);
+ parseCommaSepArgs(argc, argv, "dt-tc=", p->filters[4]);
+ parseCommaSepArgs(argc, argv, "dt-test-case-exclude=", p->filters[5]);
+ parseCommaSepArgs(argc, argv, "dt-tce=", p->filters[5]);
+ // clang-format on
+
+ int intRes = 0;
+ String strRes;
+
+#define DOCTEST_PARSE_AS_BOOL_OR_FLAG(name, sname, var, default) \
+ if(parseIntOption(argc, argv, DOCTEST_STR_CONCAT_TOSTR(name, =), option_bool, intRes) || \
+ parseIntOption(argc, argv, DOCTEST_STR_CONCAT_TOSTR(sname, =), option_bool, intRes)) \
+ p->var = !!intRes; \
+ else if(parseFlag(argc, argv, #name) || parseFlag(argc, argv, #sname)) \
+ p->var = 1; \
+ else if(withDefaults) \
+ p->var = default
+
+#define DOCTEST_PARSE_INT_OPTION(name, sname, var, default) \
+ if(parseIntOption(argc, argv, DOCTEST_STR_CONCAT_TOSTR(name, =), option_int, intRes) || \
+ parseIntOption(argc, argv, DOCTEST_STR_CONCAT_TOSTR(sname, =), option_int, intRes)) \
+ p->var = intRes; \
+ else if(withDefaults) \
+ p->var = default
+
+#define DOCTEST_PARSE_STR_OPTION(name, sname, var, default) \
+ if(parseOption(argc, argv, DOCTEST_STR_CONCAT_TOSTR(name, =), strRes, default) || \
+ parseOption(argc, argv, DOCTEST_STR_CONCAT_TOSTR(sname, =), strRes, default) || \
+ withDefaults) \
+ p->var = strRes
+
+ // clang-format off
+ DOCTEST_PARSE_STR_OPTION(dt-order-by, dt-ob, order_by, "file");
+ DOCTEST_PARSE_INT_OPTION(dt-rand-seed, dt-rs, rand_seed, 0);
+
+ DOCTEST_PARSE_INT_OPTION(dt-first, dt-f, first, 1);
+ DOCTEST_PARSE_INT_OPTION(dt-last, dt-l, last, 0);
+
+ DOCTEST_PARSE_INT_OPTION(dt-abort-after, dt-aa, abort_after, 0);
+
+ DOCTEST_PARSE_AS_BOOL_OR_FLAG(dt-success, dt-s, success, 0);
+ DOCTEST_PARSE_AS_BOOL_OR_FLAG(dt-case-sensitive, dt-cs, case_sensitive, 0);
+ DOCTEST_PARSE_AS_BOOL_OR_FLAG(dt-exit, dt-e, exit, 0);
+ DOCTEST_PARSE_AS_BOOL_OR_FLAG(dt-no-overrides, dt-no, no_overrides, 0);
+ DOCTEST_PARSE_AS_BOOL_OR_FLAG(dt-no-throw, dt-nt, no_throw, 0);
+ DOCTEST_PARSE_AS_BOOL_OR_FLAG(dt-no-exitcode, dt-ne, no_exitcode, 0);
+ DOCTEST_PARSE_AS_BOOL_OR_FLAG(dt-no-run, dt-nr, no_run, 0);
+ DOCTEST_PARSE_AS_BOOL_OR_FLAG(dt-no-colors, dt-nc, no_colors, 0);
+ DOCTEST_PARSE_AS_BOOL_OR_FLAG(dt-no-breaks, dt-nb, no_breaks, 0);
+ DOCTEST_PARSE_AS_BOOL_OR_FLAG(dt-no-path-filenames, dt-npf, no_path_in_filenames, 0);
+// clang-format on
+
+#undef DOCTEST_PARSE_STR_OPTION
+#undef DOCTEST_PARSE_INT_OPTION
+#undef DOCTEST_PARSE_AS_BOOL_OR_FLAG
+}
+
+// allows the user to add procedurally to the filters from the command line
+void Context::addFilter(const char* filter, const char* value) { setOption(filter, value); }
+
+// allows the user to override procedurally the int/bool options from the command line
+void Context::setOption(const char* option, int value) {
+ setOption(option, toString(value).c_str());
+}
+
+// allows the user to override procedurally the string options from the command line
+void Context::setOption(const char* option, const char* value) {
+ using namespace detail;
+
+ if(!p->no_overrides) {
+ String argv = String(option) + "=" + value;
+ const char* lvalue = argv.c_str();
+ parseArgs(1, &lvalue);
+ }
+}
+
+// users should query this in their main() and exit the program if true
+bool Context::shouldExit() { return p->exit; }
+
+// the main function that does all the filtering and test running
+int Context::run() {
+ using namespace detail;
+
+ getContextState() = p;
+ p->resetRunData();
+
+ // handle version, help and no_run
+ if(p->no_run || p->version || p->help) {
+ if(p->version)
+ printVersion();
+ if(p->help)
+ printHelp();
+
+ return EXIT_SUCCESS;
+ }
+
+ printVersion();
+ DOCTEST_PRINTF_COLORED("[doctest] ", Color::Cyan);
+ printf("run with \"-dt-help\" for options\n");
+
+ unsigned i = 0; // counter used for loops - here for VC6
+ const Vector<Vector<TestData> >& buckets = getRegisteredTests().getBuckets();
+
+ Vector<const TestData*> testArray;
+ for(i = 0; i < buckets.size(); i++)
+ for(unsigned k = 0; k < buckets[i].size(); k++)
+ testArray.push_back(&buckets[i][k]);
+
+ if(p->hash_table_histogram) {
+ // find the most full bucket
+ unsigned maxInBucket = 1;
+ for(i = 0; i < buckets.size(); i++)
+ if(buckets[i].size() > maxInBucket)
+ maxInBucket = buckets[i].size();
+
+ // print a prettified histogram
+ DOCTEST_PRINTF_COLORED("[doctest] ", Color::Cyan);
+ printf("hash table bucket histogram\n");
+ printf("============================================================\n");
+ printf("#bucket |count| relative count\n");
+ printf("============================================================\n");
+ for(i = 0; i < buckets.size(); i++) {
+ printf("bucket %4d |%4d |", static_cast<int>(i), buckets[i].size());
+
+ float ratio = static_cast<float>(buckets[i].size()) / static_cast<float>(maxInBucket);
+ unsigned numStars = static_cast<unsigned>(ratio * 41);
+ for(unsigned k = 0; k < numStars; ++k)
+ printf("*");
+ printf("\n");
+ }
+ printf("\n");
+ return EXIT_SUCCESS;
+ }
+
+ // sort the collected records
+ if(p->order_by.compare("file", true) == 0) {
+ qsort(testArray.data(), testArray.size(), sizeof(TestData*), fileOrderComparator);
+ } else if(p->order_by.compare("suite", true) == 0) {
+ qsort(testArray.data(), testArray.size(), sizeof(TestData*), suiteOrderComparator);
+ } else if(p->order_by.compare("name", true) == 0) {
+ qsort(testArray.data(), testArray.size(), sizeof(TestData*), nameOrderComparator);
+ } else if(p->order_by.compare("rand", true) == 0) {
+ srand(p->rand_seed);
+
+ // random_shuffle implementation
+ const TestData** first = testArray.data();
+ for(i = testArray.size() - 1; i > 0; --i) {
+ int idxToSwap = rand() % (i + 1);
+
+ const TestData* temp = first[i];
+
+ first[i] = first[idxToSwap];
+ first[idxToSwap] = temp;
+ }
+ }
+
+ if(p->list_test_cases) {
+ DOCTEST_PRINTF_COLORED("[doctest] ", Color::Cyan);
+ printf("listing all test case names\n");
+ }
+
+ HashTable<String> testSuitesPassingFilters(100);
+ if(p->list_test_suites) {
+ DOCTEST_PRINTF_COLORED("[doctest] ", Color::Cyan);
+ printf("listing all test suites\n");
+ }
+
+ unsigned numTestsPassingFilters = 0;
+ unsigned numFailed = 0;
+ // invoke the registered functions if they match the filter criteria (or just count them)
+ for(i = 0; i < testArray.size(); i++) {
+ const TestData& data = *testArray[i];
+ if(!matchesAny(data.m_file, p->filters[0], 1, p->case_sensitive))
+ continue;
+ if(matchesAny(data.m_file, p->filters[1], 0, p->case_sensitive))
+ continue;
+ if(!matchesAny(data.m_suite, p->filters[2], 1, p->case_sensitive))
+ continue;
+ if(matchesAny(data.m_suite, p->filters[3], 0, p->case_sensitive))
+ continue;
+ if(!matchesAny(data.m_name, p->filters[4], 1, p->case_sensitive))
+ continue;
+ if(matchesAny(data.m_name, p->filters[5], 0, p->case_sensitive))
+ continue;
+
+ numTestsPassingFilters++;
+
+ // do not execute the test if we are to only count the number of filter passing tests
+ if(p->count)
+ continue;
+
+ // print the name of the test and don't execute it
+ if(p->list_test_cases) {
+ printf("%s\n", data.m_name);
+ continue;
+ }
+
+ // print the name of the test suite if not done already and don't execute it
+ if(p->list_test_suites) {
+ if(!testSuitesPassingFilters.has(data.m_suite)) {
+ printf("%s\n", data.m_suite);
+ testSuitesPassingFilters.insert(data.m_suite);
+ }
+ continue;
+ }
+
+ // skip the test if it is not in the execution range
+ if((p->last < numTestsPassingFilters && p->first <= p->last) ||
+ (p->first > numTestsPassingFilters))
+ continue;
+
+ // execute the test if it passes all the filtering
+ {
+#ifdef _MSC_VER
+//__try {
+#endif // _MSC_VER
+
+ p->currentTest = &data;
+
+ // if logging successful tests - force the start log
+ p->hasLoggedCurrentTestStart = false;
+ if(p->success)
+ DOCTEST_LOG_START();
+
+ unsigned didFail = 0;
+ p->subcasesPassed.clear();
+ do {
+ // reset the assertion state
+ p->numAssertionsForCurrentTestcase = 0;
+ p->numFailedAssertionsForCurrentTestcase = 0;
+
+ // reset some of the fields for subcases (except for the set of fully passed ones)
+ p->subcasesHasSkipped = false;
+ p->subcasesCurrentLevel = 0;
+ p->subcasesEnteredLevels.clear();
+
+ // execute the test
+ didFail += callTestFunc(data.m_f);
+ p->numAssertions += p->numAssertionsForCurrentTestcase;
+
+ // exit this loop if enough assertions have failed
+ if(p->abort_after > 0 && p->numFailedAssertions >= p->abort_after)
+ p->subcasesHasSkipped = false;
+
+ // if the start has been logged
+ if(p->hasLoggedCurrentTestStart)
+ logTestEnd();
+ p->hasLoggedCurrentTestStart = false;
+
+ } while(p->subcasesHasSkipped == true);
+
+ if(didFail > 0)
+ numFailed++;
+
+ // stop executing tests if enough assertions have failed
+ if(p->abort_after > 0 && p->numFailedAssertions >= p->abort_after)
+ break;
+
+#ifdef _MSC_VER
+//} __except(1) {
+// printf("Unknown SEH exception caught!\n");
+// numFailed++;
+//}
+#endif // _MSC_VER
+ }
+ }
+
+ DOCTEST_PRINTF_COLORED(getSeparator(), Color::Yellow);
+ if(p->count || p->list_test_cases || p->list_test_suites) {
+ DOCTEST_PRINTF_COLORED("[doctest] ", Color::Cyan);
+ printf("number of tests passing the current filters: %d\n", numTestsPassingFilters);
+ } else {
+ char buff[DOCTEST_SNPRINTF_BUFFER_LENGTH];
+
+ DOCTEST_PRINTF_COLORED("[doctest] ", Color::Cyan);
+
+ DOCTEST_SNPRINTF(buff, DOCTEST_COUNTOF(buff), "test cases: %4d", numTestsPassingFilters);
+ DOCTEST_PRINTF_COLORED(buff, Color::None);
+ DOCTEST_SNPRINTF(buff, DOCTEST_COUNTOF(buff), " | ");
+ DOCTEST_PRINTF_COLORED(buff, Color::None);
+ DOCTEST_SNPRINTF(buff, DOCTEST_COUNTOF(buff), "%4d passed",
+ numTestsPassingFilters - numFailed);
+ DOCTEST_PRINTF_COLORED(buff, Color::Green);
+ DOCTEST_SNPRINTF(buff, DOCTEST_COUNTOF(buff), " | ");
+ DOCTEST_PRINTF_COLORED(buff, Color::None);
+ DOCTEST_SNPRINTF(buff, DOCTEST_COUNTOF(buff), "%4d failed\n", numFailed);
+ DOCTEST_PRINTF_COLORED(buff, Color::Red);
+
+ DOCTEST_PRINTF_COLORED("[doctest] ", Color::Cyan);
+
+ DOCTEST_SNPRINTF(buff, DOCTEST_COUNTOF(buff), "assertions: %4d", p->numAssertions);
+ DOCTEST_PRINTF_COLORED(buff, Color::None);
+ DOCTEST_SNPRINTF(buff, DOCTEST_COUNTOF(buff), " | ");
+ DOCTEST_PRINTF_COLORED(buff, Color::None);
+ DOCTEST_SNPRINTF(buff, DOCTEST_COUNTOF(buff), "%4d passed",
+ p->numAssertions - p->numFailedAssertions);
+ DOCTEST_PRINTF_COLORED(buff, Color::Green);
+ DOCTEST_SNPRINTF(buff, DOCTEST_COUNTOF(buff), " | ");
+ DOCTEST_PRINTF_COLORED(buff, Color::None);
+ DOCTEST_SNPRINTF(buff, DOCTEST_COUNTOF(buff), "%4d failed\n", p->numFailedAssertions);
+ DOCTEST_PRINTF_COLORED(buff, Color::Red);
+ }
+
+ if(numFailed && !p->no_exitcode)
+ return EXIT_FAILURE;
+ return EXIT_SUCCESS;
+}
+} // namespace doctest
+
+#endif // DOCTEST_CONFIG_DISABLE
+#endif // DOCTEST_LIBRARY_IMPLEMENTATION
+#endif // DOCTEST_CONFIG_IMPLEMENT
+
+// == THIS SUPPLIES A MAIN FUNCTION AND SHOULD BE DONE ONLY IN ONE TRANSLATION UNIT
+#if defined(DOCTEST_CONFIG_IMPLEMENT_WITH_MAIN) && !defined(DOCTEST_MAIN_CONFIGURED)
+#define DOCTEST_MAIN_CONFIGURED
+int main(int argc, char** argv) { return doctest::Context(argc, argv).run(); }
+#endif // DOCTEST_MAIN_CONFIGURED
+
+#if defined(__clang__)
+#pragma clang diagnostic pop
+#endif // __clang__
+
+#if defined(__GNUC__) && !defined(__clang__)
+#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ > 6)
+#pragma GCC diagnostic pop
+#endif // > gcc 4.6
+#endif // __GNUC__
+
+#ifdef _MSC_VER
+#pragma warning(pop)
+#endif // _MSC_VER
diff --git a/examples/alternative_macros/CMakeLists.txt b/examples/alternative_macros/CMakeLists.txt
index 5ce5ce1..5882f45 100644
--- a/examples/alternative_macros/CMakeLists.txt
+++ b/examples/alternative_macros/CMakeLists.txt
@@ -1,12 +1,12 @@
-cmake_minimum_required(VERSION 2.8)
-
-get_filename_component(PROJECT_NAME ${CMAKE_CURRENT_SOURCE_DIR} NAME)
-project(${PROJECT_NAME})
-
-include(../../scripts/common.cmake)
-
-include_directories("../../doctest/")
-
-add_executable(${PROJECT_NAME} main.cpp)
-
-add_test(NAME ${PROJECT_NAME} COMMAND $<TARGET_FILE:${PROJECT_NAME}>)
+cmake_minimum_required(VERSION 2.8)
+
+get_filename_component(PROJECT_NAME ${CMAKE_CURRENT_SOURCE_DIR} NAME)
+project(${PROJECT_NAME})
+
+include(../../scripts/common.cmake)
+
+include_directories("../../doctest/")
+
+add_executable(${PROJECT_NAME} main.cpp)
+
+add_test(NAME ${PROJECT_NAME} COMMAND $<TARGET_FILE:${PROJECT_NAME}>)
diff --git a/examples/alternative_macros/doctest_proxy.h b/examples/alternative_macros/doctest_proxy.h
index ad382d5..a8dff1c 100644
--- a/examples/alternative_macros/doctest_proxy.h
+++ b/examples/alternative_macros/doctest_proxy.h
@@ -1,39 +1,39 @@
-#ifndef DOCTEST_CONFIG_NO_SHORT_MACRO_NAMES
-#define DOCTEST_CONFIG_NO_SHORT_MACRO_NAMES
-#endif // DOCTEST_CONFIG_NO_SHORT_MACRO_NAMES
-
-// no guard for including the doctest header itself because it should support multiple inclusion
-#include "doctest.h"
-
-#ifndef MY_PROXY_MACROS
-#define MY_PROXY_MACROS
-
-#define my_testcase DOCTEST_TEST_CASE
-#define my_testcase_fixture DOCTEST_TEST_CASE_FIXTURE
-#define my_subcase DOCTEST_SUBCASE
-#define my_testsuite DOCTEST_TEST_SUITE
-#define my_testsuite_end DOCTEST_TEST_SUITE_END
-#define my_warn DOCTEST_WARN
-#define my_warn_false DOCTEST_WARN_FALSE
-#define my_warn_throws DOCTEST_WARN_THROWS
-#define my_warn_throws_as DOCTEST_WARN_THROWS_AS
-#define my_warn_nothrow DOCTEST_WARN_NOTHROW
-#define my_check DOCTEST_CHECK
-#define my_check_false DOCTEST_CHECK_FALSE
-#define my_check_throws DOCTEST_CHECK_THROWS
-#define my_check_throws_as DOCTEST_CHECK_THROWS_AS
-#define my_check_nothrow DOCTEST_CHECK_NOTHROW
-#define my_require DOCTEST_REQUIRE
-#define my_require_false DOCTEST_REQUIRE_FALSE
-#define my_require_throws DOCTEST_REQUIRE_THROWS
-#define my_require_throws_as DOCTEST_REQUIRE_THROWS_AS
-#define my_require_nothrow DOCTEST_REQUIRE_NOTHROW
-
-#define my_scenario DOCTEST_SCENARIO
-#define my_given DOCTEST_GIVEN
-#define my_when DOCTEST_WHEN
-#define my_and_when DOCTEST_AND_WHEN
-#define my_then DOCTEST_THEN
-#define my_and_then DOCTEST_AND_THEN
-
-#endif // MY_PROXY_MACROS
+#ifndef DOCTEST_CONFIG_NO_SHORT_MACRO_NAMES
+#define DOCTEST_CONFIG_NO_SHORT_MACRO_NAMES
+#endif // DOCTEST_CONFIG_NO_SHORT_MACRO_NAMES
+
+// no guard for including the doctest header itself because it should support multiple inclusion
+#include "doctest.h"
+
+#ifndef MY_PROXY_MACROS
+#define MY_PROXY_MACROS
+
+#define my_testcase DOCTEST_TEST_CASE
+#define my_testcase_fixture DOCTEST_TEST_CASE_FIXTURE
+#define my_subcase DOCTEST_SUBCASE
+#define my_testsuite DOCTEST_TEST_SUITE
+#define my_testsuite_end DOCTEST_TEST_SUITE_END
+#define my_warn DOCTEST_WARN
+#define my_warn_false DOCTEST_WARN_FALSE
+#define my_warn_throws DOCTEST_WARN_THROWS
+#define my_warn_throws_as DOCTEST_WARN_THROWS_AS
+#define my_warn_nothrow DOCTEST_WARN_NOTHROW
+#define my_check DOCTEST_CHECK
+#define my_check_false DOCTEST_CHECK_FALSE
+#define my_check_throws DOCTEST_CHECK_THROWS
+#define my_check_throws_as DOCTEST_CHECK_THROWS_AS
+#define my_check_nothrow DOCTEST_CHECK_NOTHROW
+#define my_require DOCTEST_REQUIRE
+#define my_require_false DOCTEST_REQUIRE_FALSE
+#define my_require_throws DOCTEST_REQUIRE_THROWS
+#define my_require_throws_as DOCTEST_REQUIRE_THROWS_AS
+#define my_require_nothrow DOCTEST_REQUIRE_NOTHROW
+
+#define my_scenario DOCTEST_SCENARIO
+#define my_given DOCTEST_GIVEN
+#define my_when DOCTEST_WHEN
+#define my_and_when DOCTEST_AND_WHEN
+#define my_then DOCTEST_THEN
+#define my_and_then DOCTEST_AND_THEN
+
+#endif // MY_PROXY_MACROS
diff --git a/examples/alternative_macros/main.cpp b/examples/alternative_macros/main.cpp
index 20cf249..9017111 100644
--- a/examples/alternative_macros/main.cpp
+++ b/examples/alternative_macros/main.cpp
@@ -1,19 +1,19 @@
-#define DOCTEST_CONFIG_IMPLEMENT_WITH_MAIN
-#include "doctest_proxy.h"
-
-#include <cstdio>
-
-my_testcase("custom macros") {
- printf("Hello world!\n");
-
- my_check(1 == 1);
-
- my_subcase("bar") {
- my_subcase("foo") {}
- my_subcase("baz") {}
-
- my_require(5 > 3);
- }
-
- // CHECK(1 == 1); <== ERROR - the default short macros are disabled from the proxy header
-}
+#define DOCTEST_CONFIG_IMPLEMENT_WITH_MAIN
+#include "doctest_proxy.h"
+
+#include <cstdio>
+
+my_testcase("custom macros") {
+ printf("Hello world!\n");
+
+ my_check(1 == 1);
+
+ my_subcase("bar") {
+ my_subcase("foo") {}
+ my_subcase("baz") {}
+
+ my_require(5 > 3);
+ }
+
+ // CHECK(1 == 1); <== ERROR - the default short macros are disabled from the proxy header
+}
diff --git a/examples/assertion_macros/CMakeLists.txt b/examples/assertion_macros/CMakeLists.txt
index 5ce5ce1..5882f45 100644
--- a/examples/assertion_macros/CMakeLists.txt
+++ b/examples/assertion_macros/CMakeLists.txt
@@ -1,12 +1,12 @@
-cmake_minimum_required(VERSION 2.8)
-
-get_filename_component(PROJECT_NAME ${CMAKE_CURRENT_SOURCE_DIR} NAME)
-project(${PROJECT_NAME})
-
-include(../../scripts/common.cmake)
-
-include_directories("../../doctest/")
-
-add_executable(${PROJECT_NAME} main.cpp)
-
-add_test(NAME ${PROJECT_NAME} COMMAND $<TARGET_FILE:${PROJECT_NAME}>)
+cmake_minimum_required(VERSION 2.8)
+
+get_filename_component(PROJECT_NAME ${CMAKE_CURRENT_SOURCE_DIR} NAME)
+project(${PROJECT_NAME})
+
+include(../../scripts/common.cmake)
+
+include_directories("../../doctest/")
+
+add_executable(${PROJECT_NAME} main.cpp)
+
+add_test(NAME ${PROJECT_NAME} COMMAND $<TARGET_FILE:${PROJECT_NAME}>)
diff --git a/examples/assertion_macros/main.cpp b/examples/assertion_macros/main.cpp
index 08019ab..aea7691 100644
--- a/examples/assertion_macros/main.cpp
+++ b/examples/assertion_macros/main.cpp
@@ -1,48 +1,48 @@
-#define DOCTEST_CONFIG_IMPLEMENT_WITH_MAIN
-#include "doctest.h"
-
-static int throws(bool in) {
- if(in)
- throw 5;
- return 42;
-}
-
-using doctest::Approx;
-
-TEST_SUITE("meaningless macros");
-
-TEST_CASE("an empty test that will succeed") {}
-
-TEST_CASE("an empty test that will fail because of an exception") { throws(true); }
-
-TEST_SUITE_END();
-
-TEST_CASE("normal macros") {
- int a = 5;
- int b = 5;
-
- CHECK(throws(true) == 42);
-
- CHECK_FALSE(!(a == b));
-
- REQUIRE(a == b);
- //WARN(reinterpret_cast<void*>(1000) == reinterpret_cast<void*>(1004));
-
- CHECK(Approx(0.1000001) == 0.1000002);
- CHECK(Approx(0.502) == 0.501);
-
- const char* c_string = "test_test";
-
- CHECK(c_string == "test_test");
-
- throws(true);
-}
-
-TEST_CASE("exceptions-related macros") {
- CHECK_THROWS(throws(false));
- CHECK_THROWS_AS(throws(false), int);
- CHECK_THROWS_AS(throws(true), int);
- CHECK_THROWS_AS(throws(true), char);
-
- REQUIRE_NOTHROW(throws(true));
-}
+#define DOCTEST_CONFIG_IMPLEMENT_WITH_MAIN
+#include "doctest.h"
+
+static int throws(bool in) {
+ if(in)
+ throw 5;
+ return 42;
+}
+
+using doctest::Approx;
+
+TEST_SUITE("meaningless macros");
+
+TEST_CASE("an empty test that will succeed") {}
+
+TEST_CASE("an empty test that will fail because of an exception") { throws(true); }
+
+TEST_SUITE_END();
+
+TEST_CASE("normal macros") {
+ int a = 5;
+ int b = 5;
+
+ CHECK(throws(true) == 42);
+
+ CHECK_FALSE(!(a == b));
+
+ REQUIRE(a == b);
+ //WARN(reinterpret_cast<void*>(1000) == reinterpret_cast<void*>(1004));
+
+ CHECK(Approx(0.1000001) == 0.1000002);
+ CHECK(Approx(0.502) == 0.501);
+
+ const char* c_string = "test_test";
+
+ CHECK(c_string == "test_test");
+
+ throws(true);
+}
+
+TEST_CASE("exceptions-related macros") {
+ CHECK_THROWS(throws(false));
+ CHECK_THROWS_AS(throws(false), int);
+ CHECK_THROWS_AS(throws(true), int);
+ CHECK_THROWS_AS(throws(true), char);
+
+ REQUIRE_NOTHROW(throws(true));
+}
diff --git a/examples/disabled/CMakeLists.txt b/examples/disabled/CMakeLists.txt
index 219a9e9..77efa4c 100644
--- a/examples/disabled/CMakeLists.txt
+++ b/examples/disabled/CMakeLists.txt
@@ -1,12 +1,12 @@
-cmake_minimum_required(VERSION 2.8)
-
-get_filename_component(PROJECT_NAME ${CMAKE_CURRENT_SOURCE_DIR} NAME)
-project(${PROJECT_NAME})
-
-include(../../scripts/common.cmake)
-
-include_directories("../../doctest/")
-
-add_executable(${PROJECT_NAME} main.cpp test.cpp)
-
-add_test(NAME ${PROJECT_NAME} COMMAND $<TARGET_FILE:${PROJECT_NAME}>)
+cmake_minimum_required(VERSION 2.8)
+
+get_filename_component(PROJECT_NAME ${CMAKE_CURRENT_SOURCE_DIR} NAME)
+project(${PROJECT_NAME})
+
+include(../../scripts/common.cmake)
+
+include_directories("../../doctest/")
+
+add_executable(${PROJECT_NAME} main.cpp test.cpp)
+
+add_test(NAME ${PROJECT_NAME} COMMAND $<TARGET_FILE:${PROJECT_NAME}>)
diff --git a/examples/disabled/main.cpp b/examples/disabled/main.cpp
index 94a8f68..b3064b1 100644
--- a/examples/disabled/main.cpp
+++ b/examples/disabled/main.cpp
@@ -1,24 +1,24 @@
-#define DOCTEST_CONFIG_DISABLE
-
-#define DOCTEST_CONFIG_IMPLEMENT
-#include "doctest.h"
-
-int main(int argc, char** argv) {
- doctest::Context context(argc, argv); // initialize
-
- // overrides
- context.addFilter("test-case-exclude", "*math*"); // exclude test cases with "math" in the name
- context.setOption("no-breaks", true); // don't break in the debugger when assertions fail
- context.setOption("abort-after", 5); // stop test execution after 5 failed assertions
- context.setOption("sort", "name"); // sort the test cases by their name
-
- int res = context.run(); // run
-
- if(context.shouldExit()) // important - query flags (and --no-run) rely on the user doing this
- return res; // propagate the result of the tests
-
- int client_stuff_return_code = 0;
- // your program - if the testing framework is integrated in your production code
-
- return res + client_stuff_return_code;
-}
+#define DOCTEST_CONFIG_DISABLE
+
+#define DOCTEST_CONFIG_IMPLEMENT
+#include "doctest.h"
+
+int main(int argc, char** argv) {
+ doctest::Context context(argc, argv); // initialize
+
+ // overrides
+ context.addFilter("test-case-exclude", "*math*"); // exclude test cases with "math" in the name
+ context.setOption("no-breaks", true); // don't break in the debugger when assertions fail
+ context.setOption("abort-after", 5); // stop test execution after 5 failed assertions
+ context.setOption("sort", "name"); // sort the test cases by their name
+
+ int res = context.run(); // run
+
+ if(context.shouldExit()) // important - query flags (and --no-run) rely on the user doing this
+ return res; // propagate the result of the tests
+
+ int client_stuff_return_code = 0;
+ // your program - if the testing framework is integrated in your production code
+
+ return res + client_stuff_return_code;
+}
diff --git a/examples/disabled/test.cpp b/examples/disabled/test.cpp
index edc7177..673df06 100644
--- a/examples/disabled/test.cpp
+++ b/examples/disabled/test.cpp
@@ -1,74 +1,74 @@
-#define DOCTEST_CONFIG_DISABLE
-
-#include "doctest.h"
-
-#ifdef _MSC_VER
-#pragma warning(disable : 4505) // unreferenced local functions being removed
-#endif // _MSC_VER
-
-#ifdef __clang__
-#pragma clang diagnostic ignored "-Wunneeded-internal-declaration"
-#endif // __clang__
-
-using doctest::Approx;
-
-static int throws(bool in) {
- if(in)
- throw "whops!";
- return 42;
-}
-
-TEST_SUITE("the testsuite!");
-
-#define DO_STUFF() \
- CHECK(1 == 0); \
- CHECK_FALSE(1 == 0); \
- CHECK(Approx(0.502) == 0.501); \
- CHECK(1 == 1); \
- REQUIRE(1 == 1); \
- CHECK_FALSE(0); \
- REQUIRE_FALSE(0); \
- CHECK_THROWS(throws()); \
- REQUIRE_THROWS(throws()); \
- CHECK_THROWS_AS(throws(), int); \
- REQUIRE_THROWS_AS(throws(), char); \
- CHECK_NOTHROW(nothrows()); \
- REQUIRE_NOTHROW(nothrows()); \
- SUBCASE("") {}
-
-// in a separate function because the TEST_CASE() macro will expand to an uninstantiated template
-// and we want to ensure this code is parsed (MSVC will not if it is in an uninstantiated template)
-static void f() { DO_STUFF(); }
-
-TEST_CASE("ops") {
- f();
-
- throws(false);
-
- DO_STUFF();
-}
-
-TEST_SUITE_END();
-
-// to silence GCC warnings when inheriting from the class TheFixture which has no virtual destructor
-#if defined(__GNUC__) && !defined(__clang__)
-#pragma GCC diagnostic ignored "-Weffc++"
-#endif // __GNUC__
-
-struct TheFixture
-{
- int data;
- TheFixture()
- : data(42) {
- // setup here
- }
-
- ~TheFixture() {
- // teardown here
- }
-};
-
-TEST_CASE_FIXTURE(TheFixture, "test with a fixture - 1") {
- data /= 2;
- CHECK(data == 21);
-}
+#define DOCTEST_CONFIG_DISABLE
+
+#include "doctest.h"
+
+#ifdef _MSC_VER
+#pragma warning(disable : 4505) // unreferenced local functions being removed
+#endif // _MSC_VER
+
+#ifdef __clang__
+#pragma clang diagnostic ignored "-Wunneeded-internal-declaration"
+#endif // __clang__
+
+using doctest::Approx;
+
+static int throws(bool in) {
+ if(in)
+ throw "whops!";
+ return 42;
+}
+
+TEST_SUITE("the testsuite!");
+
+#define DO_STUFF() \
+ CHECK(1 == 0); \
+ CHECK_FALSE(1 == 0); \
+ CHECK(Approx(0.502) == 0.501); \
+ CHECK(1 == 1); \
+ REQUIRE(1 == 1); \
+ CHECK_FALSE(0); \
+ REQUIRE_FALSE(0); \
+ CHECK_THROWS(throws()); \
+ REQUIRE_THROWS(throws()); \
+ CHECK_THROWS_AS(throws(), int); \
+ REQUIRE_THROWS_AS(throws(), char); \
+ CHECK_NOTHROW(nothrows()); \
+ REQUIRE_NOTHROW(nothrows()); \
+ SUBCASE("") {}
+
+// in a separate function because the TEST_CASE() macro will expand to an uninstantiated template
+// and we want to ensure this code is parsed (MSVC will not if it is in an uninstantiated template)
+static void f() { DO_STUFF(); }
+
+TEST_CASE("ops") {
+ f();
+
+ throws(false);
+
+ DO_STUFF();
+}
+
+TEST_SUITE_END();
+
+// to silence GCC warnings when inheriting from the class TheFixture which has no virtual destructor
+#if defined(__GNUC__) && !defined(__clang__)
+#pragma GCC diagnostic ignored "-Weffc++"
+#endif // __GNUC__
+
+struct TheFixture
+{
+ int data;
+ TheFixture()
+ : data(42) {
+ // setup here
+ }
+
+ ~TheFixture() {
+ // teardown here
+ }
+};
+
+TEST_CASE_FIXTURE(TheFixture, "test with a fixture - 1") {
+ data /= 2;
+ CHECK(data == 21);
+}
diff --git a/examples/dll_and_executable/CMakeLists.txt b/examples/dll_and_executable/CMakeLists.txt
index d5de538..c2c5bff 100644
--- a/examples/dll_and_executable/CMakeLists.txt
+++ b/examples/dll_and_executable/CMakeLists.txt
@@ -1,21 +1,21 @@
-cmake_minimum_required(VERSION 2.8)
-
-get_filename_component(PROJECT_NAME ${CMAKE_CURRENT_SOURCE_DIR} NAME)
-project(${PROJECT_NAME})
-
-include(../../scripts/common.cmake)
-
-if(DEFINED ENV{TRAVIS} AND APPLE)
- set(CMAKE_MACOSX_RPATH ON)
- # force 64 bit for OSX because -m32 fails >>> SOMETIMES <<< (x86_64 vs 386 - like the dll is not linked with -m32...)
- add_compiler_flags(-m64)
-endif()
-
-include_directories("../../doctest/")
-
-add_library(dll SHARED dll.cpp)
-
-add_executable(${PROJECT_NAME} main.cpp)
-target_link_libraries(${PROJECT_NAME} dll)
-
-add_test(NO_OUTPUT NAME ${PROJECT_NAME} COMMAND $<TARGET_FILE:${PROJECT_NAME}>)
+cmake_minimum_required(VERSION 2.8)
+
+get_filename_component(PROJECT_NAME ${CMAKE_CURRENT_SOURCE_DIR} NAME)
+project(${PROJECT_NAME})
+
+include(../../scripts/common.cmake)
+
+if(DEFINED ENV{TRAVIS} AND APPLE)
+ set(CMAKE_MACOSX_RPATH ON)
+ # force 64 bit for OSX because -m32 fails >>> SOMETIMES <<< (x86_64 vs 386 - like the dll is not linked with -m32...)
+ add_compiler_flags(-m64)
+endif()
+
+include_directories("../../doctest/")
+
+add_library(dll SHARED dll.cpp)
+
+add_executable(${PROJECT_NAME} main.cpp)
+target_link_libraries(${PROJECT_NAME} dll)
+
+add_test(NO_OUTPUT NAME ${PROJECT_NAME} COMMAND $<TARGET_FILE:${PROJECT_NAME}>)
diff --git a/examples/dll_and_executable/common.h b/examples/dll_and_executable/common.h
index 0d90176..5c15ed4 100644
--- a/examples/dll_and_executable/common.h
+++ b/examples/dll_and_executable/common.h
@@ -1,39 +1,39 @@
-#pragma once
-
-// taken from https://gcc.gnu.org/wiki/Visibility
-#if defined _WIN32 || defined __CYGWIN__
- #ifdef BUILDING_DLL
- #ifdef __GNUC__
- #define DLL_PUBLIC __attribute__ ((dllexport))
- #else
- #define DLL_PUBLIC __declspec(dllexport)
- #endif
- #else
- #ifdef __GNUC__
- #define DLL_PUBLIC __attribute__ ((dllimport))
- #else
- #define DLL_PUBLIC __declspec(dllimport)
- #endif
- #endif
-#else
- #ifdef BUILDING_DLL
- #if __GNUC__ >= 4
- #define DLL_PUBLIC __attribute__ ((visibility ("default")))
- #else
- #define DLL_PUBLIC
- #endif
- #else
- #define DLL_PUBLIC
- #endif
-#endif
-
-#define DOCTEST_CONFIG_IMPLEMENT
-#include "doctest.h"
-
-#include <cstdio>
-
-TEST_CASE("shared") {
- printf("I am a test in a header used by the executable and the dll!\n");
-}
-
-DLL_PUBLIC int call_tests_from_dll(int argc, char** argv);
+#pragma once
+
+// taken from https://gcc.gnu.org/wiki/Visibility
+#if defined _WIN32 || defined __CYGWIN__
+ #ifdef BUILDING_DLL
+ #ifdef __GNUC__
+ #define DLL_PUBLIC __attribute__ ((dllexport))
+ #else
+ #define DLL_PUBLIC __declspec(dllexport)
+ #endif
+ #else
+ #ifdef __GNUC__
+ #define DLL_PUBLIC __attribute__ ((dllimport))
+ #else
+ #define DLL_PUBLIC __declspec(dllimport)
+ #endif
+ #endif
+#else
+ #ifdef BUILDING_DLL
+ #if __GNUC__ >= 4
+ #define DLL_PUBLIC __attribute__ ((visibility ("default")))
+ #else
+ #define DLL_PUBLIC
+ #endif
+ #else
+ #define DLL_PUBLIC
+ #endif
+#endif
+
+#define DOCTEST_CONFIG_IMPLEMENT
+#include "doctest.h"
+
+#include <cstdio>
+
+TEST_CASE("shared") {
+ printf("I am a test in a header used by the executable and the dll!\n");
+}
+
+DLL_PUBLIC int call_tests_from_dll(int argc, char** argv);
diff --git a/examples/dll_and_executable/dll.cpp b/examples/dll_and_executable/dll.cpp
index 937a67a..f7b88a5 100644
--- a/examples/dll_and_executable/dll.cpp
+++ b/examples/dll_and_executable/dll.cpp
@@ -1,11 +1,11 @@
-#define BUILDING_DLL
-#include "common.h"
-
-TEST_CASE("dll") {
- printf("I am a test from the dll!\n");
-}
-
-DLL_PUBLIC int call_tests_from_dll(int argc, char** argv) {
- doctest::Context context(argc, argv);
- return context.run();
-}
+#define BUILDING_DLL
+#include "common.h"
+
+TEST_CASE("dll") {
+ printf("I am a test from the dll!\n");
+}
+
+DLL_PUBLIC int call_tests_from_dll(int argc, char** argv) {
+ doctest::Context context(argc, argv);
+ return context.run();
+}
diff --git a/examples/dll_and_executable/main.cpp b/examples/dll_and_executable/main.cpp
index 1d2d6e2..c0d7659 100644
--- a/examples/dll_and_executable/main.cpp
+++ b/examples/dll_and_executable/main.cpp
@@ -1,14 +1,14 @@
-#include "common.h"
-
-TEST_CASE("executable") {
- printf("I am a test from the executable!\n");
-}
-
-int main(int argc, char** argv) {
- doctest::Context context(argc, argv);
- int res = context.run();
-
- res += call_tests_from_dll(argc, argv);
-
- return res;
-}
+#include "common.h"
+
+TEST_CASE("executable") {
+ printf("I am a test from the executable!\n");
+}
+
+int main(int argc, char** argv) {
+ doctest::Context context(argc, argv);
+ int res = context.run();
+
+ res += call_tests_from_dll(argc, argv);
+
+ return res;
+}
diff --git a/examples/hello_world/CMakeLists.txt b/examples/hello_world/CMakeLists.txt
index 5ce5ce1..5882f45 100644
--- a/examples/hello_world/CMakeLists.txt
+++ b/examples/hello_world/CMakeLists.txt
@@ -1,12 +1,12 @@
-cmake_minimum_required(VERSION 2.8)
-
-get_filename_component(PROJECT_NAME ${CMAKE_CURRENT_SOURCE_DIR} NAME)
-project(${PROJECT_NAME})
-
-include(../../scripts/common.cmake)
-
-include_directories("../../doctest/")
-
-add_executable(${PROJECT_NAME} main.cpp)
-
-add_test(NAME ${PROJECT_NAME} COMMAND $<TARGET_FILE:${PROJECT_NAME}>)
+cmake_minimum_required(VERSION 2.8)
+
+get_filename_component(PROJECT_NAME ${CMAKE_CURRENT_SOURCE_DIR} NAME)
+project(${PROJECT_NAME})
+
+include(../../scripts/common.cmake)
+
+include_directories("../../doctest/")
+
+add_executable(${PROJECT_NAME} main.cpp)
+
+add_test(NAME ${PROJECT_NAME} COMMAND $<TARGET_FILE:${PROJECT_NAME}>)
diff --git a/examples/hello_world/main.cpp b/examples/hello_world/main.cpp
index 53fbc71..496e709 100644
--- a/examples/hello_world/main.cpp
+++ b/examples/hello_world/main.cpp
@@ -1,12 +1,12 @@
-#define DOCTEST_CONFIG_IMPLEMENT_WITH_MAIN
-#include "doctest.h"
-
-static int factorial(int number) { return number <= 1 ? number : factorial(number - 1) * number; }
-
-TEST_CASE("testing the factorial function") {
- CHECK(factorial(0) == 1);
- CHECK(factorial(1) == 1);
- CHECK(factorial(2) == 2);
- CHECK(factorial(3) == 6);
- CHECK(factorial(10) == 3628800);
-}
+#define DOCTEST_CONFIG_IMPLEMENT_WITH_MAIN
+#include "doctest.h"
+
+static int factorial(int number) { return number <= 1 ? number : factorial(number - 1) * number; }
+
+TEST_CASE("testing the factorial function") {
+ CHECK(factorial(0) == 1);
+ CHECK(factorial(1) == 1);
+ CHECK(factorial(2) == 2);
+ CHECK(factorial(3) == 6);
+ CHECK(factorial(10) == 3628800);
+}
diff --git a/examples/multi_file_example/CMakeLists.txt b/examples/multi_file_example/CMakeLists.txt
index 62a9250..d4e995a 100644
--- a/examples/multi_file_example/CMakeLists.txt
+++ b/examples/multi_file_example/CMakeLists.txt
@@ -1,12 +1,12 @@
-cmake_minimum_required(VERSION 2.8)
-
-get_filename_component(PROJECT_NAME ${CMAKE_CURRENT_SOURCE_DIR} NAME)
-project(${PROJECT_NAME})
-
-include(../../scripts/common.cmake)
-
-include_directories("../../doctest/")
-
-add_executable(${PROJECT_NAME} main.cpp f1.cpp f2.cpp hdr.h)
-
-add_test(NAME ${PROJECT_NAME} COMMAND $<TARGET_FILE:${PROJECT_NAME}>)
+cmake_minimum_required(VERSION 2.8)
+
+get_filename_component(PROJECT_NAME ${CMAKE_CURRENT_SOURCE_DIR} NAME)
+project(${PROJECT_NAME})
+
+include(../../scripts/common.cmake)
+
+include_directories("../../doctest/")
+
+add_executable(${PROJECT_NAME} main.cpp f1.cpp f2.cpp hdr.h)
+
+add_test(NAME ${PROJECT_NAME} COMMAND $<TARGET_FILE:${PROJECT_NAME}>)
diff --git a/examples/multi_file_example/f1.cpp b/examples/multi_file_example/f1.cpp
index 8316388..e716418 100644
--- a/examples/multi_file_example/f1.cpp
+++ b/examples/multi_file_example/f1.cpp
@@ -1 +1 @@
-#include "doctest.h"
+#include "doctest.h"
diff --git a/examples/multi_file_example/f2.cpp b/examples/multi_file_example/f2.cpp
index 8316388..e716418 100644
--- a/examples/multi_file_example/f2.cpp
+++ b/examples/multi_file_example/f2.cpp
@@ -1 +1 @@
-#include "doctest.h"
+#include "doctest.h"
diff --git a/examples/multi_file_example/hdr.h b/examples/multi_file_example/hdr.h
index 3ab6e3d..23c5c88 100644
--- a/examples/multi_file_example/hdr.h
+++ b/examples/multi_file_example/hdr.h
@@ -1,5 +1,5 @@
-#pragma once
-
-#include "doctest.h"
-
-
+#pragma once
+
+#include "doctest.h"
+
+
diff --git a/examples/multi_file_example/main.cpp b/examples/multi_file_example/main.cpp
index 6566adf..300c632 100644
--- a/examples/multi_file_example/main.cpp
+++ b/examples/multi_file_example/main.cpp
@@ -1,22 +1,22 @@
-#define DOCTEST_CONFIG_IMPLEMENT
-#include "doctest.h"
-
-int main(int argc, char** argv) {
- doctest::Context context(argc, argv); // initialize
-
- // overrides
- context.addFilter("test-case-exclude", "*math*"); // exclude test cases with "math" in their name
- context.setOption("no-breaks", true); // don't break in the debugger when assertions fail
- context.setOption("abort-after", 5); // stop test execution after 5 failed assertions
- context.setOption("sort", "name"); // sort the test cases by their name
-
- int res = context.run(); // run
-
- if(context.shouldExit()) // important - query flags (and --no-run) rely on the user doing this
- return res; // propagate the result of the tests
-
- int client_stuff_return_code = 0;
- // your program - if the testing framework is integrated in your production code
-
- return res + client_stuff_return_code;
-}
+#define DOCTEST_CONFIG_IMPLEMENT
+#include "doctest.h"
+
+int main(int argc, char** argv) {
+ doctest::Context context(argc, argv); // initialize
+
+ // overrides
+ context.addFilter("test-case-exclude", "*math*"); // exclude test cases with "math" in their name
+ context.setOption("no-breaks", true); // don't break in the debugger when assertions fail
+ context.setOption("abort-after", 5); // stop test execution after 5 failed assertions
+ context.setOption("sort", "name"); // sort the test cases by their name
+
+ int res = context.run(); // run
+
+ if(context.shouldExit()) // important - query flags (and --no-run) rely on the user doing this
+ return res; // propagate the result of the tests
+
+ int client_stuff_return_code = 0;
+ // your program - if the testing framework is integrated in your production code
+
+ return res + client_stuff_return_code;
+}
diff --git a/examples/range_based_execution/CMakeLists.txt b/examples/range_based_execution/CMakeLists.txt
index 8304f37..10f41c5 100644
--- a/examples/range_based_execution/CMakeLists.txt
+++ b/examples/range_based_execution/CMakeLists.txt
@@ -1,12 +1,12 @@
-cmake_minimum_required(VERSION 2.8)
-
-get_filename_component(PROJECT_NAME ${CMAKE_CURRENT_SOURCE_DIR} NAME)
-project(${PROJECT_NAME})
-
-include(../../scripts/common.cmake)
-
-include_directories("../../doctest/")
-
-add_executable(${PROJECT_NAME} main.cpp)
-
-add_test(NO_VALGRIND NO_OUTPUT NAME ${PROJECT_NAME}_1 COMMAND python ${CMAKE_CURRENT_SOURCE_DIR}/run.py $<TARGET_FILE:${PROJECT_NAME}>)
+cmake_minimum_required(VERSION 2.8)
+
+get_filename_component(PROJECT_NAME ${CMAKE_CURRENT_SOURCE_DIR} NAME)
+project(${PROJECT_NAME})
+
+include(../../scripts/common.cmake)
+
+include_directories("../../doctest/")
+
+add_executable(${PROJECT_NAME} main.cpp)
+
+add_test(NO_VALGRIND NO_OUTPUT NAME ${PROJECT_NAME}_1 COMMAND python ${CMAKE_CURRENT_SOURCE_DIR}/run.py $<TARGET_FILE:${PROJECT_NAME}>)
diff --git a/examples/range_based_execution/main.cpp b/examples/range_based_execution/main.cpp
index 8c0acf4..bd9df22 100644
--- a/examples/range_based_execution/main.cpp
+++ b/examples/range_based_execution/main.cpp
@@ -1,114 +1,114 @@
-#define DOCTEST_CONFIG_IMPLEMENT_WITH_MAIN
-#include "doctest.h"
-
-#include <cstdio>
-
-static void sleeper(int line) {
-#ifdef NDEBUG
- for(int i = 0; i < 50000000; i++) ((void)0);
-#else
- for(int i = 0; i < 10000000; i++) ((void)0);
-#endif
- printf("hello from test case %d!\n", line);
-}
-
-TEST_CASE("") { sleeper(__LINE__ - 14); }
-TEST_CASE("") { sleeper(__LINE__ - 14); }
-TEST_CASE("") { sleeper(__LINE__ - 14); }
-TEST_CASE("") { sleeper(__LINE__ - 14); }
-TEST_CASE("") { sleeper(__LINE__ - 14); }
-TEST_CASE("") { sleeper(__LINE__ - 14); }
-TEST_CASE("") { sleeper(__LINE__ - 14); }
-TEST_CASE("") { sleeper(__LINE__ - 14); }
-TEST_CASE("") { sleeper(__LINE__ - 14); }
-TEST_CASE("") { sleeper(__LINE__ - 14); }
-TEST_CASE("") { sleeper(__LINE__ - 14); }
-TEST_CASE("") { sleeper(__LINE__ - 14); }
-TEST_CASE("") { sleeper(__LINE__ - 14); }
-TEST_CASE("") { sleeper(__LINE__ - 14); }
-TEST_CASE("") { sleeper(__LINE__ - 14); }
-TEST_CASE("") { sleeper(__LINE__ - 14); }
-TEST_CASE("") { sleeper(__LINE__ - 14); }
-TEST_CASE("") { sleeper(__LINE__ - 14); }
-TEST_CASE("") { sleeper(__LINE__ - 14); }
-TEST_CASE("") { sleeper(__LINE__ - 14); }
-TEST_CASE("") { sleeper(__LINE__ - 14); }
-TEST_CASE("") { sleeper(__LINE__ - 14); }
-TEST_CASE("") { sleeper(__LINE__ - 14); }
-TEST_CASE("") { sleeper(__LINE__ - 14); }
-TEST_CASE("") { sleeper(__LINE__ - 14); }
-TEST_CASE("") { sleeper(__LINE__ - 14); }
-TEST_CASE("") { sleeper(__LINE__ - 14); }
-TEST_CASE("") { sleeper(__LINE__ - 14); }
-TEST_CASE("") { sleeper(__LINE__ - 14); }
-TEST_CASE("") { sleeper(__LINE__ - 14); }
-TEST_CASE("") { sleeper(__LINE__ - 14); }
-TEST_CASE("") { sleeper(__LINE__ - 14); }
-TEST_CASE("") { sleeper(__LINE__ - 14); }
-TEST_CASE("") { sleeper(__LINE__ - 14); }
-TEST_CASE("") { sleeper(__LINE__ - 14); }
-TEST_CASE("") { sleeper(__LINE__ - 14); }
-TEST_CASE("") { sleeper(__LINE__ - 14); }
-TEST_CASE("") { sleeper(__LINE__ - 14); }
-TEST_CASE("") { sleeper(__LINE__ - 14); }
-TEST_CASE("") { sleeper(__LINE__ - 14); }
-TEST_CASE("") { sleeper(__LINE__ - 14); }
-TEST_CASE("") { sleeper(__LINE__ - 14); }
-TEST_CASE("") { sleeper(__LINE__ - 14); }
-TEST_CASE("") { sleeper(__LINE__ - 14); }
-TEST_CASE("") { sleeper(__LINE__ - 14); }
-TEST_CASE("") { sleeper(__LINE__ - 14); }
-TEST_CASE("") { sleeper(__LINE__ - 14); }
-TEST_CASE("") { sleeper(__LINE__ - 14); }
-TEST_CASE("") { sleeper(__LINE__ - 14); }
-TEST_CASE("") { sleeper(__LINE__ - 14); }
-TEST_CASE("") { sleeper(__LINE__ - 14); }
-TEST_CASE("") { sleeper(__LINE__ - 14); }
-TEST_CASE("") { sleeper(__LINE__ - 14); }
-TEST_CASE("") { sleeper(__LINE__ - 14); }
-TEST_CASE("") { sleeper(__LINE__ - 14); }
-TEST_CASE("") { sleeper(__LINE__ - 14); }
-TEST_CASE("") { sleeper(__LINE__ - 14); }
-TEST_CASE("") { sleeper(__LINE__ - 14); }
-TEST_CASE("") { sleeper(__LINE__ - 14); }
-TEST_CASE("") { sleeper(__LINE__ - 14); }
-TEST_CASE("") { sleeper(__LINE__ - 14); }
-TEST_CASE("") { sleeper(__LINE__ - 14); }
-TEST_CASE("") { sleeper(__LINE__ - 14); }
-TEST_CASE("") { sleeper(__LINE__ - 14); }
-TEST_CASE("") { sleeper(__LINE__ - 14); }
-TEST_CASE("") { sleeper(__LINE__ - 14); }
-TEST_CASE("") { sleeper(__LINE__ - 14); }
-TEST_CASE("") { sleeper(__LINE__ - 14); }
-TEST_CASE("") { sleeper(__LINE__ - 14); }
-TEST_CASE("") { sleeper(__LINE__ - 14); }
-TEST_CASE("") { sleeper(__LINE__ - 14); }
-TEST_CASE("") { sleeper(__LINE__ - 14); }
-TEST_CASE("") { sleeper(__LINE__ - 14); }
-TEST_CASE("") { sleeper(__LINE__ - 14); }
-TEST_CASE("") { sleeper(__LINE__ - 14); }
-TEST_CASE("") { sleeper(__LINE__ - 14); }
-TEST_CASE("") { sleeper(__LINE__ - 14); }
-TEST_CASE("") { sleeper(__LINE__ - 14); }
-TEST_CASE("") { sleeper(__LINE__ - 14); }
-TEST_CASE("") { sleeper(__LINE__ - 14); }
-TEST_CASE("") { sleeper(__LINE__ - 14); }
-TEST_CASE("") { sleeper(__LINE__ - 14); }
-TEST_CASE("") { sleeper(__LINE__ - 14); }
-TEST_CASE("") { sleeper(__LINE__ - 14); }
-TEST_CASE("") { sleeper(__LINE__ - 14); }
-TEST_CASE("") { sleeper(__LINE__ - 14); }
-TEST_CASE("") { sleeper(__LINE__ - 14); }
-TEST_CASE("") { sleeper(__LINE__ - 14); }
-TEST_CASE("") { sleeper(__LINE__ - 14); }
-TEST_CASE("") { sleeper(__LINE__ - 14); }
-TEST_CASE("") { sleeper(__LINE__ - 14); }
-TEST_CASE("") { sleeper(__LINE__ - 14); }
-TEST_CASE("") { sleeper(__LINE__ - 14); }
-TEST_CASE("") { sleeper(__LINE__ - 14); }
-TEST_CASE("") { sleeper(__LINE__ - 14); }
-TEST_CASE("") { sleeper(__LINE__ - 14); }
-TEST_CASE("") { sleeper(__LINE__ - 14); }
-TEST_CASE("") { sleeper(__LINE__ - 14); }
-TEST_CASE("") { sleeper(__LINE__ - 14); }
-TEST_CASE("") { sleeper(__LINE__ - 14); }
+#define DOCTEST_CONFIG_IMPLEMENT_WITH_MAIN
+#include "doctest.h"
+
+#include <cstdio>
+
+static void sleeper(int line) {
+#ifdef NDEBUG
+ for(int i = 0; i < 50000000; i++) ((void)0);
+#else
+ for(int i = 0; i < 10000000; i++) ((void)0);
+#endif
+ printf("hello from test case %d!\n", line);
+}
+
+TEST_CASE("") { sleeper(__LINE__ - 14); }
+TEST_CASE("") { sleeper(__LINE__ - 14); }
+TEST_CASE("") { sleeper(__LINE__ - 14); }
+TEST_CASE("") { sleeper(__LINE__ - 14); }
+TEST_CASE("") { sleeper(__LINE__ - 14); }
+TEST_CASE("") { sleeper(__LINE__ - 14); }
+TEST_CASE("") { sleeper(__LINE__ - 14); }
+TEST_CASE("") { sleeper(__LINE__ - 14); }
+TEST_CASE("") { sleeper(__LINE__ - 14); }
+TEST_CASE("") { sleeper(__LINE__ - 14); }
+TEST_CASE("") { sleeper(__LINE__ - 14); }
+TEST_CASE("") { sleeper(__LINE__ - 14); }
+TEST_CASE("") { sleeper(__LINE__ - 14); }
+TEST_CASE("") { sleeper(__LINE__ - 14); }
+TEST_CASE("") { sleeper(__LINE__ - 14); }
+TEST_CASE("") { sleeper(__LINE__ - 14); }
+TEST_CASE("") { sleeper(__LINE__ - 14); }
+TEST_CASE("") { sleeper(__LINE__ - 14); }
+TEST_CASE("") { sleeper(__LINE__ - 14); }
+TEST_CASE("") { sleeper(__LINE__ - 14); }
+TEST_CASE("") { sleeper(__LINE__ - 14); }
+TEST_CASE("") { sleeper(__LINE__ - 14); }
+TEST_CASE("") { sleeper(__LINE__ - 14); }
+TEST_CASE("") { sleeper(__LINE__ - 14); }
+TEST_CASE("") { sleeper(__LINE__ - 14); }
+TEST_CASE("") { sleeper(__LINE__ - 14); }
+TEST_CASE("") { sleeper(__LINE__ - 14); }
+TEST_CASE("") { sleeper(__LINE__ - 14); }
+TEST_CASE("") { sleeper(__LINE__ - 14); }
+TEST_CASE("") { sleeper(__LINE__ - 14); }
+TEST_CASE("") { sleeper(__LINE__ - 14); }
+TEST_CASE("") { sleeper(__LINE__ - 14); }
+TEST_CASE("") { sleeper(__LINE__ - 14); }
+TEST_CASE("") { sleeper(__LINE__ - 14); }
+TEST_CASE("") { sleeper(__LINE__ - 14); }
+TEST_CASE("") { sleeper(__LINE__ - 14); }
+TEST_CASE("") { sleeper(__LINE__ - 14); }
+TEST_CASE("") { sleeper(__LINE__ - 14); }
+TEST_CASE("") { sleeper(__LINE__ - 14); }
+TEST_CASE("") { sleeper(__LINE__ - 14); }
+TEST_CASE("") { sleeper(__LINE__ - 14); }
+TEST_CASE("") { sleeper(__LINE__ - 14); }
+TEST_CASE("") { sleeper(__LINE__ - 14); }
+TEST_CASE("") { sleeper(__LINE__ - 14); }
+TEST_CASE("") { sleeper(__LINE__ - 14); }
+TEST_CASE("") { sleeper(__LINE__ - 14); }
+TEST_CASE("") { sleeper(__LINE__ - 14); }
+TEST_CASE("") { sleeper(__LINE__ - 14); }
+TEST_CASE("") { sleeper(__LINE__ - 14); }
+TEST_CASE("") { sleeper(__LINE__ - 14); }
+TEST_CASE("") { sleeper(__LINE__ - 14); }
+TEST_CASE("") { sleeper(__LINE__ - 14); }
+TEST_CASE("") { sleeper(__LINE__ - 14); }
+TEST_CASE("") { sleeper(__LINE__ - 14); }
+TEST_CASE("") { sleeper(__LINE__ - 14); }
+TEST_CASE("") { sleeper(__LINE__ - 14); }
+TEST_CASE("") { sleeper(__LINE__ - 14); }
+TEST_CASE("") { sleeper(__LINE__ - 14); }
+TEST_CASE("") { sleeper(__LINE__ - 14); }
+TEST_CASE("") { sleeper(__LINE__ - 14); }
+TEST_CASE("") { sleeper(__LINE__ - 14); }
+TEST_CASE("") { sleeper(__LINE__ - 14); }
+TEST_CASE("") { sleeper(__LINE__ - 14); }
+TEST_CASE("") { sleeper(__LINE__ - 14); }
+TEST_CASE("") { sleeper(__LINE__ - 14); }
+TEST_CASE("") { sleeper(__LINE__ - 14); }
+TEST_CASE("") { sleeper(__LINE__ - 14); }
+TEST_CASE("") { sleeper(__LINE__ - 14); }
+TEST_CASE("") { sleeper(__LINE__ - 14); }
+TEST_CASE("") { sleeper(__LINE__ - 14); }
+TEST_CASE("") { sleeper(__LINE__ - 14); }
+TEST_CASE("") { sleeper(__LINE__ - 14); }
+TEST_CASE("") { sleeper(__LINE__ - 14); }
+TEST_CASE("") { sleeper(__LINE__ - 14); }
+TEST_CASE("") { sleeper(__LINE__ - 14); }
+TEST_CASE("") { sleeper(__LINE__ - 14); }
+TEST_CASE("") { sleeper(__LINE__ - 14); }
+TEST_CASE("") { sleeper(__LINE__ - 14); }
+TEST_CASE("") { sleeper(__LINE__ - 14); }
+TEST_CASE("") { sleeper(__LINE__ - 14); }
+TEST_CASE("") { sleeper(__LINE__ - 14); }
+TEST_CASE("") { sleeper(__LINE__ - 14); }
+TEST_CASE("") { sleeper(__LINE__ - 14); }
+TEST_CASE("") { sleeper(__LINE__ - 14); }
+TEST_CASE("") { sleeper(__LINE__ - 14); }
+TEST_CASE("") { sleeper(__LINE__ - 14); }
+TEST_CASE("") { sleeper(__LINE__ - 14); }
+TEST_CASE("") { sleeper(__LINE__ - 14); }
+TEST_CASE("") { sleeper(__LINE__ - 14); }
+TEST_CASE("") { sleeper(__LINE__ - 14); }
+TEST_CASE("") { sleeper(__LINE__ - 14); }
+TEST_CASE("") { sleeper(__LINE__ - 14); }
+TEST_CASE("") { sleeper(__LINE__ - 14); }
+TEST_CASE("") { sleeper(__LINE__ - 14); }
+TEST_CASE("") { sleeper(__LINE__ - 14); }
+TEST_CASE("") { sleeper(__LINE__ - 14); }
+TEST_CASE("") { sleeper(__LINE__ - 14); }
+TEST_CASE("") { sleeper(__LINE__ - 14); }
+TEST_CASE("") { sleeper(__LINE__ - 14); }
+TEST_CASE("") { sleeper(__LINE__ - 14); }
diff --git a/examples/stringification/CMakeLists.txt b/examples/stringification/CMakeLists.txt
index 5ce5ce1..5882f45 100644
--- a/examples/stringification/CMakeLists.txt
+++ b/examples/stringification/CMakeLists.txt
@@ -1,12 +1,12 @@
-cmake_minimum_required(VERSION 2.8)
-
-get_filename_component(PROJECT_NAME ${CMAKE_CURRENT_SOURCE_DIR} NAME)
-project(${PROJECT_NAME})
-
-include(../../scripts/common.cmake)
-
-include_directories("../../doctest/")
-
-add_executable(${PROJECT_NAME} main.cpp)
-
-add_test(NAME ${PROJECT_NAME} COMMAND $<TARGET_FILE:${PROJECT_NAME}>)
+cmake_minimum_required(VERSION 2.8)
+
+get_filename_component(PROJECT_NAME ${CMAKE_CURRENT_SOURCE_DIR} NAME)
+project(${PROJECT_NAME})
+
+include(../../scripts/common.cmake)
+
+include_directories("../../doctest/")
+
+add_executable(${PROJECT_NAME} main.cpp)
+
+add_test(NAME ${PROJECT_NAME} COMMAND $<TARGET_FILE:${PROJECT_NAME}>)
diff --git a/examples/stringification/main.cpp b/examples/stringification/main.cpp
index 82ff2ee..a217ac1 100644
--- a/examples/stringification/main.cpp
+++ b/examples/stringification/main.cpp
@@ -1,127 +1,127 @@
-#define DOCTEST_CONFIG_IMPLEMENT_WITH_MAIN
-#include "doctest.h"
-
-#include <string>
-#include <vector>
-#include <list>
-
-#include <sstream>
-
-// the standard forbids writing in the std namespace but it works on all compilers
-namespace std
-{
-template <typename T>
-ostream& operator<<(ostream& stream, const vector<T>& in) {
- stream << "[";
- for(size_t i = 0; i < in.size(); ++i)
- if(i < in.size() - 1)
- stream << in[i] << ", ";
- else
- stream << in[i];
- stream << "]";
- return stream;
-}
-}
-
-// as an alternative you may write a specialization of doctest::StringMaker
-namespace doctest
-{
-template <typename T>
-struct StringMaker<std::list<T> >
-{
- static String convert(const std::list<T>& in) {
- std::ostringstream oss;
-
- oss << "[";
- for(typename std::list<T>::const_iterator it = in.begin(); it != in.end(); ++it)
- oss << *it << ", ";
- oss << "]";
-
- return oss.str().c_str();
- }
-};
-}
-
-// to silence GCC warnings when inheriting from the class MyType which has no virtual destructor
-#if defined(__GNUC__) && !defined(__clang__)
-#pragma GCC diagnostic ignored "-Weffc++"
-#endif // __GNUC__
-
-template <typename T, typename K>
-struct MyType
-{
- T one;
- K two;
-};
-
-template <typename T>
-struct MyTypeInherited : MyType<T, float>
-{};
-
-template <typename T, typename K>
-bool operator==(const MyType<T, K>& lhs, const MyType<T, K>& rhs) {
- return lhs.one == rhs.one && lhs.two == rhs.two;
-}
-
-template <typename T, typename K>
-std::ostream& operator<<(std::ostream& stream, const MyType<T, K>& in) {
- stream << "[" << in.one << ", " << in.two << "]";
- return stream;
-}
-
-struct Foo
-{};
-
-static bool operator==(const Foo&, const Foo&) { return false; }
-
-// as a third option you may specialize the doctest::toString() template function
-namespace doctest
-{
-template <>
-String toString(const Foo&) {
- return "Foo{}";
-}
-}
-
-TEST_CASE("the only test") {
- MyTypeInherited<int> bla1;
- bla1.one = 5;
- bla1.two = 4.0f;
- MyTypeInherited<int> bla2;
- bla2.one = 5;
- bla2.two = 6.0f;
-
- Foo f1;
- Foo f2;
- CHECK(f1 == f2);
-
- // std::string already has an operator<< working with std::ostream
- std::string dummy1 = "omg";
- std::string dummy2 = "tralala";
-
- CHECK(dummy1 == dummy2);
-
- std::vector<int> vec1;
- vec1.push_back(1);
- vec1.push_back(2);
- vec1.push_back(3);
-
- std::vector<int> vec2;
- vec2.push_back(1);
- vec2.push_back(2);
- vec2.push_back(4);
-
- CHECK(vec1 == vec2);
-
- std::list<int> lst_1;
- lst_1.push_back(1);
- lst_1.push_back(42);
- lst_1.push_back(3);
-
- std::list<int> lst_2;
- lst_2.push_back(1);
- lst_2.push_back(2);
- lst_2.push_back(666);
-
- CHECK(lst_1 == lst_2);
-}
+#define DOCTEST_CONFIG_IMPLEMENT_WITH_MAIN
+#include "doctest.h"
+
+#include <string>
+#include <vector>
+#include <list>
+
+#include <sstream>
+
+// the standard forbids writing in the std namespace but it works on all compilers
+namespace std
+{
+template <typename T>
+ostream& operator<<(ostream& stream, const vector<T>& in) {
+ stream << "[";
+ for(size_t i = 0; i < in.size(); ++i)
+ if(i < in.size() - 1)
+ stream << in[i] << ", ";
+ else
+ stream << in[i];
+ stream << "]";
+ return stream;
+}
+}
+
+// as an alternative you may write a specialization of doctest::StringMaker
+namespace doctest
+{
+template <typename T>
+struct StringMaker<std::list<T> >
+{
+ static String convert(const std::list<T>& in) {
+ std::ostringstream oss;
+
+ oss << "[";
+ for(typename std::list<T>::const_iterator it = in.begin(); it != in.end(); ++it)
+ oss << *it << ", ";
+ oss << "]";
+
+ return oss.str().c_str();
+ }
+};
+}
+
+// to silence GCC warnings when inheriting from the class MyType which has no virtual destructor
+#if defined(__GNUC__) && !defined(__clang__)
+#pragma GCC diagnostic ignored "-Weffc++"
+#endif // __GNUC__
+
+template <typename T, typename K>
+struct MyType
+{
+ T one;
+ K two;
+};
+
+template <typename T>
+struct MyTypeInherited : MyType<T, float>
+{};
+
+template <typename T, typename K>
+bool operator==(const MyType<T, K>& lhs, const MyType<T, K>& rhs) {
+ return lhs.one == rhs.one && lhs.two == rhs.two;
+}
+
+template <typename T, typename K>
+std::ostream& operator<<(std::ostream& stream, const MyType<T, K>& in) {
+ stream << "[" << in.one << ", " << in.two << "]";
+ return stream;
+}
+
+struct Foo
+{};
+
+static bool operator==(const Foo&, const Foo&) { return false; }
+
+// as a third option you may specialize the doctest::toString() template function
+namespace doctest
+{
+template <>
+String toString(const Foo&) {
+ return "Foo{}";
+}
+}
+
+TEST_CASE("the only test") {
+ MyTypeInherited<int> bla1;
+ bla1.one = 5;
+ bla1.two = 4.0f;
+ MyTypeInherited<int> bla2;
+ bla2.one = 5;
+ bla2.two = 6.0f;
+
+ Foo f1;
+ Foo f2;
+ CHECK(f1 == f2);
+
+ // std::string already has an operator<< working with std::ostream
+ std::string dummy1 = "omg";
+ std::string dummy2 = "tralala";
+
+ CHECK(dummy1 == dummy2);
+
+ std::vector<int> vec1;
+ vec1.push_back(1);
+ vec1.push_back(2);
+ vec1.push_back(3);
+
+ std::vector<int> vec2;
+ vec2.push_back(1);
+ vec2.push_back(2);
+ vec2.push_back(4);
+
+ CHECK(vec1 == vec2);
+
+ std::list<int> lst_1;
+ lst_1.push_back(1);
+ lst_1.push_back(42);
+ lst_1.push_back(3);
+
+ std::list<int> lst_2;
+ lst_2.push_back(1);
+ lst_2.push_back(2);
+ lst_2.push_back(666);
+
+ CHECK(lst_1 == lst_2);
+}
diff --git a/examples/subcases_and_bdd/CMakeLists.txt b/examples/subcases_and_bdd/CMakeLists.txt
index c9a6410..d301715 100644
--- a/examples/subcases_and_bdd/CMakeLists.txt
+++ b/examples/subcases_and_bdd/CMakeLists.txt
@@ -1,18 +1,18 @@
-cmake_minimum_required(VERSION 2.8)
-
-get_filename_component(PROJECT_NAME ${CMAKE_CURRENT_SOURCE_DIR} NAME)
-project(${PROJECT_NAME})
-
-include(../../scripts/common.cmake)
-
-include_directories("../../doctest/")
-
-add_executable(${PROJECT_NAME} main.cpp)
-
-if(DEFINED ENV{TRAVIS} AND APPLE AND CMAKE_CXX_COMPILER_ID MATCHES "GNU" AND CMAKE_CXX_COMPILER_VERSION VERSION_LESS 4.5)
- # don't do tests for GCC 4.4 - the reference output will be different
- # for some reason after an exception is thrown the program quits even though it should be caught
- return()
-endif()
-
-add_test(NAME ${PROJECT_NAME} COMMAND $<TARGET_FILE:${PROJECT_NAME}>)
+cmake_minimum_required(VERSION 2.8)
+
+get_filename_component(PROJECT_NAME ${CMAKE_CURRENT_SOURCE_DIR} NAME)
+project(${PROJECT_NAME})
+
+include(../../scripts/common.cmake)
+
+include_directories("../../doctest/")
+
+add_executable(${PROJECT_NAME} main.cpp)
+
+if(DEFINED ENV{TRAVIS} AND APPLE AND CMAKE_CXX_COMPILER_ID MATCHES "GNU" AND CMAKE_CXX_COMPILER_VERSION VERSION_LESS 4.5)
+ # don't do tests for GCC 4.4 - the reference output will be different
+ # for some reason after an exception is thrown the program quits even though it should be caught
+ return()
+endif()
+
+add_test(NAME ${PROJECT_NAME} COMMAND $<TARGET_FILE:${PROJECT_NAME}>)
diff --git a/examples/subcases_and_bdd/main.cpp b/examples/subcases_and_bdd/main.cpp
index 837f99e..4a608f0 100644
--- a/examples/subcases_and_bdd/main.cpp
+++ b/examples/subcases_and_bdd/main.cpp
@@ -1,107 +1,107 @@
-#define DOCTEST_CONFIG_IMPLEMENT_WITH_MAIN
-#include "doctest.h"
-
-#include <iostream>
-#include <vector>
-using namespace std;
-
-static int throws(bool in) {
- if(in)
- throw 5;
- return 42;
-}
-
-TEST_CASE("lots of nested subcases") {
- cout << endl << "root" << endl;
- SUBCASE("") {
- cout << "1" << endl;
- SUBCASE("") { cout << "1.1" << endl; }
- }
- SUBCASE("") {
- cout << "2" << endl;
- SUBCASE("") { cout << "2.1" << endl; }
- SUBCASE("") {
- // whops! all the subcases below shouldn't be discovered and executed!
- throws(true);
-
- cout << "2.2" << endl;
- SUBCASE("") {
- cout << "2.2.1" << endl;
- SUBCASE("") { cout << "2.2.1.1" << endl; }
- SUBCASE("") { cout << "2.2.1.2" << endl; }
- }
- }
- SUBCASE("") { cout << "2.3" << endl; }
- SUBCASE("") { cout << "2.4" << endl; }
- }
-}
-
-SCENARIO("vectors can be sized and resized") {
- GIVEN("A vector with some items") {
- std::vector<int> v(5);
-
- REQUIRE(v.size() == 5u);
- REQUIRE(v.capacity() >= 5u);
-
- WHEN("the size is increased") {
- v.resize(10u);
-
- THEN("the size and capacity change") {
- CHECK(v.size() == 20u);
- CHECK(v.capacity() >= 10u);
- }
- }
- WHEN("the size is reduced") {
- v.resize(0);
-
- THEN("the size changes but not capacity") {
- CHECK(v.size() == 0u);
- CHECK(v.capacity() >= 5u);
- }
- }
- WHEN("more capacity is reserved") {
- v.reserve(10);
-
- THEN("the capacity changes but not the size") {
- CHECK(v.size() == 5u);
- CHECK(v.capacity() >= 10u);
- }
- }
- WHEN("less capacity is reserved") {
- v.reserve(0);
-
- THEN("neither size nor capacity are changed") {
- CHECK(v.size() == 10u);
- CHECK(v.capacity() >= 5u);
- }
- }
- }
-}
-
-// to silence GCC warnings when inheriting from the class TheFixture which has no virtual destructor
-#if defined(__GNUC__) && !defined(__clang__)
-#pragma GCC diagnostic ignored "-Weffc++"
-#endif // __GNUC__
-
-struct TheFixture
-{
- int data;
- TheFixture()
- : data(42) {
- // setup here
- }
-
- ~TheFixture() {
- // teardown here
- }
-};
-
-TEST_CASE_FIXTURE(TheFixture, "test with a fixture - 1") {
- data /= 2;
- CHECK(data == 21);
-}
-
-TEST_CASE_FIXTURE(TheFixture, "test with a fixture - 2") {
- data *= 2;
- CHECK(data == 85);
-}
+#define DOCTEST_CONFIG_IMPLEMENT_WITH_MAIN
+#include "doctest.h"
+
+#include <iostream>
+#include <vector>
+using namespace std;
+
+static int throws(bool in) {
+ if(in)
+ throw 5;
+ return 42;
+}
+
+TEST_CASE("lots of nested subcases") {
+ cout << endl << "root" << endl;
+ SUBCASE("") {
+ cout << "1" << endl;
+ SUBCASE("") { cout << "1.1" << endl; }
+ }
+ SUBCASE("") {
+ cout << "2" << endl;
+ SUBCASE("") { cout << "2.1" << endl; }
+ SUBCASE("") {
+ // whops! all the subcases below shouldn't be discovered and executed!
+ throws(true);
+
+ cout << "2.2" << endl;
+ SUBCASE("") {
+ cout << "2.2.1" << endl;
+ SUBCASE("") { cout << "2.2.1.1" << endl; }
+ SUBCASE("") { cout << "2.2.1.2" << endl; }
+ }
+ }
+ SUBCASE("") { cout << "2.3" << endl; }
+ SUBCASE("") { cout << "2.4" << endl; }
+ }
+}
+
+SCENARIO("vectors can be sized and resized") {
+ GIVEN("A vector with some items") {
+ std::vector<int> v(5);
+
+ REQUIRE(v.size() == 5u);
+ REQUIRE(v.capacity() >= 5u);
+
+ WHEN("the size is increased") {
+ v.resize(10u);
+
+ THEN("the size and capacity change") {
+ CHECK(v.size() == 20u);
+ CHECK(v.capacity() >= 10u);
+ }
+ }
+ WHEN("the size is reduced") {
+ v.resize(0);
+
+ THEN("the size changes but not capacity") {
+ CHECK(v.size() == 0u);
+ CHECK(v.capacity() >= 5u);
+ }
+ }
+ WHEN("more capacity is reserved") {
+ v.reserve(10);
+
+ THEN("the capacity changes but not the size") {
+ CHECK(v.size() == 5u);
+ CHECK(v.capacity() >= 10u);
+ }
+ }
+ WHEN("less capacity is reserved") {
+ v.reserve(0);
+
+ THEN("neither size nor capacity are changed") {
+ CHECK(v.size() == 10u);
+ CHECK(v.capacity() >= 5u);
+ }
+ }
+ }
+}
+
+// to silence GCC warnings when inheriting from the class TheFixture which has no virtual destructor
+#if defined(__GNUC__) && !defined(__clang__)
+#pragma GCC diagnostic ignored "-Weffc++"
+#endif // __GNUC__
+
+struct TheFixture
+{
+ int data;
+ TheFixture()
+ : data(42) {
+ // setup here
+ }
+
+ ~TheFixture() {
+ // teardown here
+ }
+};
+
+TEST_CASE_FIXTURE(TheFixture, "test with a fixture - 1") {
+ data /= 2;
+ CHECK(data == 21);
+}
+
+TEST_CASE_FIXTURE(TheFixture, "test with a fixture - 2") {
+ data *= 2;
+ CHECK(data == 85);
+}
diff --git a/examples/user_supplied_main/CMakeLists.txt b/examples/user_supplied_main/CMakeLists.txt
index 5ce5ce1..5882f45 100644
--- a/examples/user_supplied_main/CMakeLists.txt
+++ b/examples/user_supplied_main/CMakeLists.txt
@@ -1,12 +1,12 @@
-cmake_minimum_required(VERSION 2.8)
-
-get_filename_component(PROJECT_NAME ${CMAKE_CURRENT_SOURCE_DIR} NAME)
-project(${PROJECT_NAME})
-
-include(../../scripts/common.cmake)
-
-include_directories("../../doctest/")
-
-add_executable(${PROJECT_NAME} main.cpp)
-
-add_test(NAME ${PROJECT_NAME} COMMAND $<TARGET_FILE:${PROJECT_NAME}>)
+cmake_minimum_required(VERSION 2.8)
+
+get_filename_component(PROJECT_NAME ${CMAKE_CURRENT_SOURCE_DIR} NAME)
+project(${PROJECT_NAME})
+
+include(../../scripts/common.cmake)
+
+include_directories("../../doctest/")
+
+add_executable(${PROJECT_NAME} main.cpp)
+
+add_test(NAME ${PROJECT_NAME} COMMAND $<TARGET_FILE:${PROJECT_NAME}>)
diff --git a/examples/user_supplied_main/main.cpp b/examples/user_supplied_main/main.cpp
index ba5ec5e..f7232c6 100644
--- a/examples/user_supplied_main/main.cpp
+++ b/examples/user_supplied_main/main.cpp
@@ -1,34 +1,34 @@
-#define DOCTEST_CONFIG_IMPLEMENT
-#include "doctest.h"
-
-int main(int argc, char** argv) {
- doctest::Context context(argc, argv); // initialize
-
- // overrides
- context.addFilter("test-case-exclude", "*math*"); // exclude test cases with "math" in the name
- context.setOption("no-breaks", true); // don't break in the debugger when assertions fail
- context.setOption("abort-after", 5); // stop test execution after 5 failed assertions
- context.setOption("sort", "name"); // sort the test cases by their name
-
- int res = context.run(); // run
-
- if(context.shouldExit()) // important - query flags (and --no-run) rely on the user doing this
- return res; // propagate the result of the tests
-
- int client_stuff_return_code = 0;
- // your program - if the testing framework is integrated in your production code
-
- return res + client_stuff_return_code;
-}
-
-#include <string>
-
-TEST_CASE("[string] testing std::string") {
- std::string a("omg");
- CHECK(a == "omg");
-}
-
-TEST_CASE("[math] basic stuff") {
- CHECK(6 > 5);
- CHECK(6 > 7);
-}
+#define DOCTEST_CONFIG_IMPLEMENT
+#include "doctest.h"
+
+int main(int argc, char** argv) {
+ doctest::Context context(argc, argv); // initialize
+
+ // overrides
+ context.addFilter("test-case-exclude", "*math*"); // exclude test cases with "math" in the name
+ context.setOption("no-breaks", true); // don't break in the debugger when assertions fail
+ context.setOption("abort-after", 5); // stop test execution after 5 failed assertions
+ context.setOption("sort", "name"); // sort the test cases by their name
+
+ int res = context.run(); // run
+
+ if(context.shouldExit()) // important - query flags (and --no-run) rely on the user doing this
+ return res; // propagate the result of the tests
+
+ int client_stuff_return_code = 0;
+ // your program - if the testing framework is integrated in your production code
+
+ return res + client_stuff_return_code;
+}
+
+#include <string>
+
+TEST_CASE("[string] testing std::string") {
+ std::string a("omg");
+ CHECK(a == "omg");
+}
+
+TEST_CASE("[math] basic stuff") {
+ CHECK(6 > 5);
+ CHECK(6 > 7);
+}
diff --git a/scripts/common.cmake b/scripts/common.cmake
index 0bd9c47..b7fd72c 100644
--- a/scripts/common.cmake
+++ b/scripts/common.cmake
@@ -1,144 +1,144 @@
-if(common_included)
- return()
-endif()
-set(common_included true)
-
-include(CMakeParseArguments)
-
-# cache this for use inside of the function
-set(CURRENT_LIST_DIR_CACHED ${CMAKE_CURRENT_LIST_DIR})
-
-enable_testing()
-
-set(TEST_MODE "COMPARE" CACHE STRING "Test mode - normal/run through valgrind/collect output/compare with output")
-set_property(CACHE TEST_MODE PROPERTY STRINGS "NORMAL;VALGRIND;COLLECT;COMPARE")
-
-# add a customized overloaded version of add_test() to suite my needs
-function(add_test)
- cmake_parse_arguments(ARG "NO_VALGRIND;NO_OUTPUT" "NAME" "COMMAND" ${ARGN})
- if(NOT "${ARG_UNPARSED_ARGUMENTS}" STREQUAL "" OR "${ARG_NAME}" STREQUAL "" OR "${ARG_COMMAND}" STREQUAL "")
- message(FATAL_ERROR "add_test() called with wrong options!")
- endif()
-
- set(the_test_mode NORMAL)
-
- # construct the command that will be called by the exec_test.cmake script
- set(the_command "")
- if(${TEST_MODE} STREQUAL "VALGRIND" AND NOT ARG_NO_VALGRIND)
- set(the_test_mode VALGRIND)
- set(the_command "valgrind -v --leak-check=full --track-origins=yes --error-exitcode=1")
- endif()
- foreach(cur ${ARG_COMMAND})
- set(the_command "${the_command} ${cur}")
- endforeach()
- # append the argument for removing paths from filenames in the output so tests give the same output everywhere
- set(the_command "${the_command} --dt-no-path-filenames=1")
- set(the_command "${the_command} --dt-no-exitcode=1")
-
- string(STRIP ${the_command} the_command)
-
- if(${TEST_MODE} STREQUAL "COLLECT" OR ${TEST_MODE} STREQUAL "COMPARE")
- if(NOT ARG_NO_OUTPUT)
- file(MAKE_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/test_output/)
- set(the_test_mode ${TEST_MODE})
- list(APPEND ADDITIONAL_FLAGS -DTEST_OUTPUT_FILE=${CMAKE_CURRENT_SOURCE_DIR}/test_output/${ARG_NAME}.txt)
- list(APPEND ADDITIONAL_FLAGS -DTEST_TEMP_FILE=${CMAKE_CURRENT_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/temp_test_output.txt)
- endif()
- endif()
-
- list(APPEND ADDITIONAL_FLAGS -DTEST_MODE=${the_test_mode})
-
- _add_test(NAME ${ARG_NAME} COMMAND ${CMAKE_COMMAND} -DCOMMAND=${the_command} ${ADDITIONAL_FLAGS} -P ${CURRENT_LIST_DIR_CACHED}/exec_test.cmake)
-endfunction()
-
-macro(add_compiler_flags)
- foreach(flag ${ARGV})
- set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${flag}")
- endforeach()
-endmacro()
-
-if(CMAKE_CXX_COMPILER_ID MATCHES "GNU|Clang")
- add_compiler_flags(-Werror)
- add_compiler_flags(-std=c++98)
- add_compiler_flags(-pedantic)
- add_compiler_flags(-pedantic-errors)
- add_compiler_flags(-fvisibility=hidden)
- add_compiler_flags(-fstrict-aliasing)
-endif()
-
-if(CMAKE_CXX_COMPILER_ID MATCHES "GNU")
- add_compiler_flags(-ansi)
- add_compiler_flags(-Wall)
- add_compiler_flags(-Wextra)
- add_compiler_flags(-fstack-protector-all)
- add_compiler_flags(-funsafe-loop-optimizations)
- add_compiler_flags(-fdiagnostics-show-option)
- add_compiler_flags(-Wconversion)
- add_compiler_flags(-Wno-missing-field-initializers)
- add_compiler_flags(-Wold-style-cast)
- add_compiler_flags(-Wfloat-equal)
- add_compiler_flags(-Wlogical-op)
- add_compiler_flags(-Wundef)
- add_compiler_flags(-Wredundant-decls)
- add_compiler_flags(-Wshadow)
- add_compiler_flags(-Wstrict-overflow=5)
- add_compiler_flags(-Wwrite-strings)
- add_compiler_flags(-Wpointer-arith)
- add_compiler_flags(-Wcast-qual)
- add_compiler_flags(-Wformat=2)
- add_compiler_flags(-Wswitch-default)
- add_compiler_flags(-Wmissing-include-dirs)
- add_compiler_flags(-Wcast-align)
- add_compiler_flags(-Wformat-nonliteral)
- add_compiler_flags(-Wparentheses)
- add_compiler_flags(-Winit-self)
- add_compiler_flags(-Wuninitialized)
- add_compiler_flags(-Wswitch-enum)
- add_compiler_flags(-Wno-endif-labels)
- add_compiler_flags(-Wunused-function)
- add_compiler_flags(-Wnon-virtual-dtor)
- add_compiler_flags(-Wno-pmf-conversions)
- add_compiler_flags(-Wctor-dtor-privacy)
- add_compiler_flags(-Wsign-promo)
- add_compiler_flags(-Wsign-conversion)
- add_compiler_flags(-Wdisabled-optimization)
- add_compiler_flags(-Weffc++)
- add_compiler_flags(-Winline)
- add_compiler_flags(-Winvalid-pch)
- add_compiler_flags(-Wstack-protector)
- add_compiler_flags(-Wunsafe-loop-optimizations)
- add_compiler_flags(-Wmissing-declarations)
- add_compiler_flags(-Woverloaded-virtual)
- add_compiler_flags(-Wstrict-null-sentinel)
- if(NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 4.6)
- add_compiler_flags(-Wnoexcept)
- endif()
- #add_compiler_flags(-Waggregate-return) # GCC 4.8 does not silence this even with "#pragma GCC diagnostic ignored"
-
- if(NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 5.0)
- add_compiler_flags(-Wdouble-promotion)
- add_compiler_flags(-Wtrampolines)
- add_compiler_flags(-Wzero-as-null-pointer-constant)
- add_compiler_flags(-Wuseless-cast)
- add_compiler_flags(-Wvector-operation-performance)
- add_compiler_flags(-Wsized-deallocation)
- endif()
-
- if(CMAKE_CXX_COMPILER_VERSION VERSION_GREATER 5.3)
- add_compiler_flags(-Wshift-overflow=2)
- add_compiler_flags(-Wnull-dereference)
- add_compiler_flags(-Wduplicated-cond)
- add_compiler_flags(-Wmisleading-indentation)
- add_compiler_flags(-Wshift-negative-value)
- endif()
-endif()
-
-if(CMAKE_CXX_COMPILER_ID MATCHES "Clang")
- add_compiler_flags(-Weverything)
- add_compiler_flags(-Qunused-arguments -fcolor-diagnostics) # needed for ccache integration on travis
-endif()
-
-if(CMAKE_CXX_COMPILER_ID MATCHES "MSVC")
- add_compiler_flags(/WX)
- add_compiler_flags(/W4) # /Wall is too aggressive - even the standard C headers give thousands of errors...
-endif()
+if(common_included)
+ return()
+endif()
+set(common_included true)
+
+include(CMakeParseArguments)
+
+# cache this for use inside of the function
+set(CURRENT_LIST_DIR_CACHED ${CMAKE_CURRENT_LIST_DIR})
+
+enable_testing()
+
+set(TEST_MODE "COMPARE" CACHE STRING "Test mode - normal/run through valgrind/collect output/compare with output")
+set_property(CACHE TEST_MODE PROPERTY STRINGS "NORMAL;VALGRIND;COLLECT;COMPARE")
+
+# add a customized overloaded version of add_test() to suite my needs
+function(add_test)
+ cmake_parse_arguments(ARG "NO_VALGRIND;NO_OUTPUT" "NAME" "COMMAND" ${ARGN})
+ if(NOT "${ARG_UNPARSED_ARGUMENTS}" STREQUAL "" OR "${ARG_NAME}" STREQUAL "" OR "${ARG_COMMAND}" STREQUAL "")
+ message(FATAL_ERROR "add_test() called with wrong options!")
+ endif()
+
+ set(the_test_mode NORMAL)
+
+ # construct the command that will be called by the exec_test.cmake script
+ set(the_command "")
+ if(${TEST_MODE} STREQUAL "VALGRIND" AND NOT ARG_NO_VALGRIND)
+ set(the_test_mode VALGRIND)
+ set(the_command "valgrind -v --leak-check=full --track-origins=yes --error-exitcode=1")
+ endif()
+ foreach(cur ${ARG_COMMAND})
+ set(the_command "${the_command} ${cur}")
+ endforeach()
+ # append the argument for removing paths from filenames in the output so tests give the same output everywhere
+ set(the_command "${the_command} --dt-no-path-filenames=1")
+ set(the_command "${the_command} --dt-no-exitcode=1")
+
+ string(STRIP ${the_command} the_command)
+
+ if(${TEST_MODE} STREQUAL "COLLECT" OR ${TEST_MODE} STREQUAL "COMPARE")
+ if(NOT ARG_NO_OUTPUT)
+ file(MAKE_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/test_output/)
+ set(the_test_mode ${TEST_MODE})
+ list(APPEND ADDITIONAL_FLAGS -DTEST_OUTPUT_FILE=${CMAKE_CURRENT_SOURCE_DIR}/test_output/${ARG_NAME}.txt)
+ list(APPEND ADDITIONAL_FLAGS -DTEST_TEMP_FILE=${CMAKE_CURRENT_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/temp_test_output.txt)
+ endif()
+ endif()
+
+ list(APPEND ADDITIONAL_FLAGS -DTEST_MODE=${the_test_mode})
+
+ _add_test(NAME ${ARG_NAME} COMMAND ${CMAKE_COMMAND} -DCOMMAND=${the_command} ${ADDITIONAL_FLAGS} -P ${CURRENT_LIST_DIR_CACHED}/exec_test.cmake)
+endfunction()
+
+macro(add_compiler_flags)
+ foreach(flag ${ARGV})
+ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${flag}")
+ endforeach()
+endmacro()
+
+if(CMAKE_CXX_COMPILER_ID MATCHES "GNU|Clang")
+ add_compiler_flags(-Werror)
+ add_compiler_flags(-std=c++98)
+ add_compiler_flags(-pedantic)
+ add_compiler_flags(-pedantic-errors)
+ add_compiler_flags(-fvisibility=hidden)
+ add_compiler_flags(-fstrict-aliasing)
+endif()
+
+if(CMAKE_CXX_COMPILER_ID MATCHES "GNU")
+ add_compiler_flags(-ansi)
+ add_compiler_flags(-Wall)
+ add_compiler_flags(-Wextra)
+ add_compiler_flags(-fstack-protector-all)
+ add_compiler_flags(-funsafe-loop-optimizations)
+ add_compiler_flags(-fdiagnostics-show-option)
+ add_compiler_flags(-Wconversion)
+ add_compiler_flags(-Wno-missing-field-initializers)
+ add_compiler_flags(-Wold-style-cast)
+ add_compiler_flags(-Wfloat-equal)
+ add_compiler_flags(-Wlogical-op)
+ add_compiler_flags(-Wundef)
+ add_compiler_flags(-Wredundant-decls)
+ add_compiler_flags(-Wshadow)
+ add_compiler_flags(-Wstrict-overflow=5)
+ add_compiler_flags(-Wwrite-strings)
+ add_compiler_flags(-Wpointer-arith)
+ add_compiler_flags(-Wcast-qual)
+ add_compiler_flags(-Wformat=2)
+ add_compiler_flags(-Wswitch-default)
+ add_compiler_flags(-Wmissing-include-dirs)
+ add_compiler_flags(-Wcast-align)
+ add_compiler_flags(-Wformat-nonliteral)
+ add_compiler_flags(-Wparentheses)
+ add_compiler_flags(-Winit-self)
+ add_compiler_flags(-Wuninitialized)
+ add_compiler_flags(-Wswitch-enum)
+ add_compiler_flags(-Wno-endif-labels)
+ add_compiler_flags(-Wunused-function)
+ add_compiler_flags(-Wnon-virtual-dtor)
+ add_compiler_flags(-Wno-pmf-conversions)
+ add_compiler_flags(-Wctor-dtor-privacy)
+ add_compiler_flags(-Wsign-promo)
+ add_compiler_flags(-Wsign-conversion)
+ add_compiler_flags(-Wdisabled-optimization)
+ add_compiler_flags(-Weffc++)
+ add_compiler_flags(-Winline)
+ add_compiler_flags(-Winvalid-pch)
+ add_compiler_flags(-Wstack-protector)
+ add_compiler_flags(-Wunsafe-loop-optimizations)
+ add_compiler_flags(-Wmissing-declarations)
+ add_compiler_flags(-Woverloaded-virtual)
+ add_compiler_flags(-Wstrict-null-sentinel)
+ if(NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 4.6)
+ add_compiler_flags(-Wnoexcept)
+ endif()
+ #add_compiler_flags(-Waggregate-return) # GCC 4.8 does not silence this even with "#pragma GCC diagnostic ignored"
+
+ if(NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 5.0)
+ add_compiler_flags(-Wdouble-promotion)
+ add_compiler_flags(-Wtrampolines)
+ add_compiler_flags(-Wzero-as-null-pointer-constant)
+ add_compiler_flags(-Wuseless-cast)
+ add_compiler_flags(-Wvector-operation-performance)
+ add_compiler_flags(-Wsized-deallocation)
+ endif()
+
+ if(CMAKE_CXX_COMPILER_VERSION VERSION_GREATER 5.3)
+ add_compiler_flags(-Wshift-overflow=2)
+ add_compiler_flags(-Wnull-dereference)
+ add_compiler_flags(-Wduplicated-cond)
+ add_compiler_flags(-Wmisleading-indentation)
+ add_compiler_flags(-Wshift-negative-value)
+ endif()
+endif()
+
+if(CMAKE_CXX_COMPILER_ID MATCHES "Clang")
+ add_compiler_flags(-Weverything)
+ add_compiler_flags(-Qunused-arguments -fcolor-diagnostics) # needed for ccache integration on travis
+endif()
+
+if(CMAKE_CXX_COMPILER_ID MATCHES "MSVC")
+ add_compiler_flags(/WX)
+ add_compiler_flags(/W4) # /Wall is too aggressive - even the standard C headers give thousands of errors...
+endif()
diff --git a/scripts/exec_test.cmake b/scripts/exec_test.cmake
index 64847b6..cc37039 100644
--- a/scripts/exec_test.cmake
+++ b/scripts/exec_test.cmake
@@ -1,54 +1,54 @@
-# Arguments:
-# - COMMAND: the command to run with all it's arguments
-# - TEST_MODE: NORMAL/VALGRIND/COLLECT/COMPARE
-# - TEST_OUTPUT_FILE: the file to/from which to write/read the output of the test
-# - TEST_TEMP_FILE: the temp file for the current test output used in COMPARE mode
-# To run something through this script use cmake like this:
-# cmake -DCOMMAND=path/to/my.exe -arg1 -arg2 -DTEST_MODE=VALGRIND -P path/to/exec_test.cmake
-
-#message("COMMAND: ${COMMAND}")
-#message("TEST_MODE: ${TEST_MODE}")
-#message("TEST_OUTPUT_FILE: ${TEST_OUTPUT_FILE}")
-#message("TEST_TEMP_FILE: ${TEST_TEMP_FILE}")
-
-string(REPLACE " " ";" COMMAND_LIST ${COMMAND})
-set(cmd COMMAND ${COMMAND_LIST} RESULT_VARIABLE CMD_RESULT)
-if("${TEST_MODE}" STREQUAL "COLLECT")
- list(APPEND cmd OUTPUT_FILE ${TEST_OUTPUT_FILE} ERROR_FILE ${TEST_OUTPUT_FILE})
-elseif("${TEST_MODE}" STREQUAL "COMPARE")
- list(APPEND cmd OUTPUT_FILE ${TEST_TEMP_FILE} ERROR_FILE ${TEST_TEMP_FILE})
-endif()
-
-execute_process(${cmd})
-
-# fix line endings
-if("${TEST_MODE}" STREQUAL "COLLECT" AND NOT CMAKE_HOST_UNIX)
- execute_process(COMMAND dos2unix ${TEST_OUTPUT_FILE})
-endif()
-
-if("${TEST_MODE}" STREQUAL "COMPARE")
- if(NOT CMAKE_HOST_UNIX)
- execute_process(COMMAND dos2unix ${TEST_TEMP_FILE})
- endif()
-
- execute_process(COMMAND ${CMAKE_COMMAND} -E compare_files ${TEST_OUTPUT_FILE} ${TEST_TEMP_FILE} RESULT_VARIABLE cmp_result)
-
- if(cmp_result)
- file(READ ${TEST_OUTPUT_FILE} orig)
- file(READ ${TEST_TEMP_FILE} temp)
-
- message("==========================================================================")
- message("== CONTENTS OF ${TEST_OUTPUT_FILE}")
- message("==========================================================================")
- message("${orig}")
- message("==========================================================================")
- message("== CONTENTS OF ${TEST_TEMP_FILE}")
- message("==========================================================================")
- message("${temp}")
- set(CMD_RESULT "Output is different from reference file!")
- endif()
-endif()
-
-if(CMD_RESULT)
- message(FATAL_ERROR "Running '${COMMAND}' ended with code '${CMD_RESULT}'")
-endif()
+# Arguments:
+# - COMMAND: the command to run with all it's arguments
+# - TEST_MODE: NORMAL/VALGRIND/COLLECT/COMPARE
+# - TEST_OUTPUT_FILE: the file to/from which to write/read the output of the test
+# - TEST_TEMP_FILE: the temp file for the current test output used in COMPARE mode
+# To run something through this script use cmake like this:
+# cmake -DCOMMAND=path/to/my.exe -arg1 -arg2 -DTEST_MODE=VALGRIND -P path/to/exec_test.cmake
+
+#message("COMMAND: ${COMMAND}")
+#message("TEST_MODE: ${TEST_MODE}")
+#message("TEST_OUTPUT_FILE: ${TEST_OUTPUT_FILE}")
+#message("TEST_TEMP_FILE: ${TEST_TEMP_FILE}")
+
+string(REPLACE " " ";" COMMAND_LIST ${COMMAND})
+set(cmd COMMAND ${COMMAND_LIST} RESULT_VARIABLE CMD_RESULT)
+if("${TEST_MODE}" STREQUAL "COLLECT")
+ list(APPEND cmd OUTPUT_FILE ${TEST_OUTPUT_FILE} ERROR_FILE ${TEST_OUTPUT_FILE})
+elseif("${TEST_MODE}" STREQUAL "COMPARE")
+ list(APPEND cmd OUTPUT_FILE ${TEST_TEMP_FILE} ERROR_FILE ${TEST_TEMP_FILE})
+endif()
+
+execute_process(${cmd})
+
+# fix line endings
+if("${TEST_MODE}" STREQUAL "COLLECT" AND NOT CMAKE_HOST_UNIX)
+ execute_process(COMMAND dos2unix ${TEST_OUTPUT_FILE})
+endif()
+
+if("${TEST_MODE}" STREQUAL "COMPARE")
+ if(NOT CMAKE_HOST_UNIX)
+ execute_process(COMMAND dos2unix ${TEST_TEMP_FILE})
+ endif()
+
+ execute_process(COMMAND ${CMAKE_COMMAND} -E compare_files ${TEST_OUTPUT_FILE} ${TEST_TEMP_FILE} RESULT_VARIABLE cmp_result)
+
+ if(cmp_result)
+ file(READ ${TEST_OUTPUT_FILE} orig)
+ file(READ ${TEST_TEMP_FILE} temp)
+
+ message("==========================================================================")
+ message("== CONTENTS OF ${TEST_OUTPUT_FILE}")
+ message("==========================================================================")
+ message("${orig}")
+ message("==========================================================================")
+ message("== CONTENTS OF ${TEST_TEMP_FILE}")
+ message("==========================================================================")
+ message("${temp}")
+ set(CMD_RESULT "Output is different from reference file!")
+ endif()
+endif()
+
+if(CMD_RESULT)
+ message(FATAL_ERROR "Running '${COMMAND}' ended with code '${CMD_RESULT}'")
+endif()
diff --git a/scripts/how_subcases_work/CMakeLists.txt b/scripts/how_subcases_work/CMakeLists.txt
index 7785439..2069071 100644
--- a/scripts/how_subcases_work/CMakeLists.txt
+++ b/scripts/how_subcases_work/CMakeLists.txt
@@ -1,6 +1,6 @@
-cmake_minimum_required(VERSION 2.8)
-
-get_filename_component(PROJECT_NAME ${CMAKE_CURRENT_SOURCE_DIR} NAME)
-project(${PROJECT_NAME})
-
-add_executable(${PROJECT_NAME} main.cpp)
+cmake_minimum_required(VERSION 2.8)
+
+get_filename_component(PROJECT_NAME ${CMAKE_CURRENT_SOURCE_DIR} NAME)
+project(${PROJECT_NAME})
+
+add_executable(${PROJECT_NAME} main.cpp)
diff --git a/scripts/how_subcases_work/main.cpp b/scripts/how_subcases_work/main.cpp
index 60121d5..0654176 100644
--- a/scripts/how_subcases_work/main.cpp
+++ b/scripts/how_subcases_work/main.cpp
@@ -1,116 +1,116 @@
-/* THE OUTPUT IS:
-
-creating empty vector
-+ 2
-== size: 2
-+ 2
-== size: 4
-
-creating empty vector
-+ 2
-== size: 2
-+ 1
-== size: 3
-
-creating empty vector
-+ 1
-== size: 1
-
-*/
-
-#include <iostream>
-#include <vector>
-#include <set>
-
-using namespace std;
-
-set<pair<const char*, int> > passed_subcases;
-set<int> entered_levels;
-int current_level;
-bool has_skipped;
-
-struct Subcase {
- Subcase(const char* file, int line)
- : m_entered(false)
- , m_file(file)
- , m_line(line)
- {
- m_entered = false;
-
- // if we have already completed it
- if(passed_subcases.count(pair<const char*, int>(file, line)) != 0)
- return;
-
- // if a Subcase on the same level has already been entered
- if(entered_levels.count(current_level) != 0) {
- has_skipped = true;
- return;
- }
-
- entered_levels.insert(current_level++);
-
- m_entered = true;
- }
-
- ~Subcase() {
- if(m_entered) {
- current_level--;
- // only mark the subcase as passed if no subcases have been skipped
- if(has_skipped == false)
- passed_subcases.insert(pair<const char*, int>(m_file, m_line));
- }
- }
-
- operator bool() const { return m_entered; }
-
- bool m_entered;
- const char* m_file;
- int m_line;
-};
-
-#define STR_CONCAT_IMPL(s1, s2) s1##s2
-#define STR_CONCAT(s1, s2) STR_CONCAT_IMPL(s1, s2)
-#define ANON_VAR STR_CONCAT(anon, __LINE__)
-
-#define subcase(title) if(const Subcase& ANON_VAR = Subcase(__FILE__, __LINE__))
-
-void test() {
- cout << endl << "creating empty vector" << endl;
- vector<int> data;
-
- subcase("size should grow to 2") {
- cout << "+ 2" << endl;
- data.push_back(42);
- data.push_back(10);
- cout << "== size: " << data.size() << endl;
-
- subcase("size should grow to 4") {
- cout << "+ 2" << endl;
- data.push_back(666);
- data.push_back(100);
- cout << "== size: " << data.size() << endl;
- }
- subcase("size should grow to 3") {
- cout << "+ 1" << endl;
- data.push_back(666);
- cout << "== size: " << data.size() << endl;
- }
- }
- subcase("size should grow to 1") {
- cout << "+ 1" << endl;
- data.push_back(42);
- cout << "== size: " << data.size() << endl;
- }
-}
-
-int main() {
- passed_subcases.clear();
- do {
- has_skipped = false;
- current_level = 0;
- entered_levels.clear();
- test();
- } while(has_skipped == true);
-
- return 0;
-}
+/* THE OUTPUT IS:
+
+creating empty vector
++ 2
+== size: 2
++ 2
+== size: 4
+
+creating empty vector
++ 2
+== size: 2
++ 1
+== size: 3
+
+creating empty vector
++ 1
+== size: 1
+
+*/
+
+#include <iostream>
+#include <vector>
+#include <set>
+
+using namespace std;
+
+set<pair<const char*, int> > passed_subcases;
+set<int> entered_levels;
+int current_level;
+bool has_skipped;
+
+struct Subcase {
+ Subcase(const char* file, int line)
+ : m_entered(false)
+ , m_file(file)
+ , m_line(line)
+ {
+ m_entered = false;
+
+ // if we have already completed it
+ if(passed_subcases.count(pair<const char*, int>(file, line)) != 0)
+ return;
+
+ // if a Subcase on the same level has already been entered
+ if(entered_levels.count(current_level) != 0) {
+ has_skipped = true;
+ return;
+ }
+
+ entered_levels.insert(current_level++);
+
+ m_entered = true;
+ }
+
+ ~Subcase() {
+ if(m_entered) {
+ current_level--;
+ // only mark the subcase as passed if no subcases have been skipped
+ if(has_skipped == false)
+ passed_subcases.insert(pair<const char*, int>(m_file, m_line));
+ }
+ }
+
+ operator bool() const { return m_entered; }
+
+ bool m_entered;
+ const char* m_file;
+ int m_line;
+};
+
+#define STR_CONCAT_IMPL(s1, s2) s1##s2
+#define STR_CONCAT(s1, s2) STR_CONCAT_IMPL(s1, s2)
+#define ANON_VAR STR_CONCAT(anon, __LINE__)
+
+#define subcase(title) if(const Subcase& ANON_VAR = Subcase(__FILE__, __LINE__))
+
+void test() {
+ cout << endl << "creating empty vector" << endl;
+ vector<int> data;
+
+ subcase("size should grow to 2") {
+ cout << "+ 2" << endl;
+ data.push_back(42);
+ data.push_back(10);
+ cout << "== size: " << data.size() << endl;
+
+ subcase("size should grow to 4") {
+ cout << "+ 2" << endl;
+ data.push_back(666);
+ data.push_back(100);
+ cout << "== size: " << data.size() << endl;
+ }
+ subcase("size should grow to 3") {
+ cout << "+ 1" << endl;
+ data.push_back(666);
+ cout << "== size: " << data.size() << endl;
+ }
+ }
+ subcase("size should grow to 1") {
+ cout << "+ 1" << endl;
+ data.push_back(42);
+ cout << "== size: " << data.size() << endl;
+ }
+}
+
+int main() {
+ passed_subcases.clear();
+ do {
+ has_skipped = false;
+ current_level = 0;
+ entered_levels.clear();
+ test();
+ } while(has_skipped == true);
+
+ return 0;
+}
diff --git a/scripts/linker_stress_test/CMakeLists.txt b/scripts/linker_stress_test/CMakeLists.txt
index cfeaee7..a9b5c26 100644
--- a/scripts/linker_stress_test/CMakeLists.txt
+++ b/scripts/linker_stress_test/CMakeLists.txt
@@ -1,22 +1,22 @@
-cmake_minimum_required(VERSION 2.8)
-
-if(CMAKE_CXX_COMPILER_ID MATCHES "GNU|Clang")
- # Clang stalls on linking this example - shame... - hope it gets a lot faster in the future
- # GCC just takes a lot of time - but I want faster travis builds
- return()
-endif()
-
-get_filename_component(PROJECT_NAME ${CMAKE_CURRENT_SOURCE_DIR} NAME)
-project(${PROJECT_NAME})
-
-include(../common.cmake)
-
-include_directories("../../doctest/")
-
-if(MSVC)
- add_definitions(/bigobj)
-endif()
-
-add_executable(${PROJECT_NAME} main.cpp test.cpp)
-
-add_test(NAME ${PROJECT_NAME} COMMAND $<TARGET_FILE:${PROJECT_NAME}>)
+cmake_minimum_required(VERSION 2.8)
+
+if(CMAKE_CXX_COMPILER_ID MATCHES "GNU|Clang")
+ # Clang stalls on linking this example - shame... - hope it gets a lot faster in the future
+ # GCC just takes a lot of time - but I want faster travis builds
+ return()
+endif()
+
+get_filename_component(PROJECT_NAME ${CMAKE_CURRENT_SOURCE_DIR} NAME)
+project(${PROJECT_NAME})
+
+include(../common.cmake)
+
+include_directories("../../doctest/")
+
+if(MSVC)
+ add_definitions(/bigobj)
+endif()
+
+add_executable(${PROJECT_NAME} main.cpp test.cpp)
+
+add_test(NAME ${PROJECT_NAME} COMMAND $<TARGET_FILE:${PROJECT_NAME}>)
diff --git a/scripts/linker_stress_test/main.cpp b/scripts/linker_stress_test/main.cpp
index 5bf4cfb..ed7df5a 100644
--- a/scripts/linker_stress_test/main.cpp
+++ b/scripts/linker_stress_test/main.cpp
@@ -1,12 +1,12 @@
-#define DOCTEST_CONFIG_IMPLEMENT_WITH_MAIN
-#include "doctest.h"
-#include "stress.inl"
-#include "stress.inl"
-#include "stress.inl"
-#include "stress.inl"
-#include "stress.inl"
-#include "stress.inl"
-#include "stress.inl"
-#include "stress.inl"
-#include "stress.inl"
-#include "stress.inl"
+#define DOCTEST_CONFIG_IMPLEMENT_WITH_MAIN
+#include "doctest.h"
+#include "stress.inl"
+#include "stress.inl"
+#include "stress.inl"
+#include "stress.inl"
+#include "stress.inl"
+#include "stress.inl"
+#include "stress.inl"
+#include "stress.inl"
+#include "stress.inl"
+#include "stress.inl"
diff --git a/scripts/linker_stress_test/readme.txt b/scripts/linker_stress_test/readme.txt
index 30889e3..f5fed10 100644
--- a/scripts/linker_stress_test/readme.txt
+++ b/scripts/linker_stress_test/readme.txt
@@ -1,27 +1,27 @@
-Machine:
- intel i7 3770k
- 16g ram
- ssd
-OS:
- windows 7 x64
- ubuntu 14.04
-Compilers:
- MinGW:
- gcc (x86_64-posix-seh-rev1, Built by MinGW-W64 project) 4.9.0
- MSVC:
- MSVC 2013
- Linux GCC:
- gcc (Ubuntu 4.8.2-19ubuntu1) 4.8.2
-
-Test consists of: 10k doctests in each of the 2 cpp files.
-
-gcc (mingw/linux): "-std=c++98 -m64"
-
-debug build:
- mingw: 121 sec (~100 sec link time)
- msvc: 11 sec
- linux: 11 sec (~1 sec link time)
-release build:
- mingw: 148 sec
- msvc: 21 sec
- linux: 24 sec
+Machine:
+ intel i7 3770k
+ 16g ram
+ ssd
+OS:
+ windows 7 x64
+ ubuntu 14.04
+Compilers:
+ MinGW:
+ gcc (x86_64-posix-seh-rev1, Built by MinGW-W64 project) 4.9.0
+ MSVC:
+ MSVC 2013
+ Linux GCC:
+ gcc (Ubuntu 4.8.2-19ubuntu1) 4.8.2
+
+Test consists of: 10k doctests in each of the 2 cpp files.
+
+gcc (mingw/linux): "-std=c++98 -m64"
+
+debug build:
+ mingw: 121 sec (~100 sec link time)
+ msvc: 11 sec
+ linux: 11 sec (~1 sec link time)
+release build:
+ mingw: 148 sec
+ msvc: 21 sec
+ linux: 24 sec
diff --git a/scripts/linker_stress_test/stress.inl b/scripts/linker_stress_test/stress.inl
index 325a447..89e587b 100644
--- a/scripts/linker_stress_test/stress.inl
+++ b/scripts/linker_stress_test/stress.inl
@@ -1,1000 +1,1000 @@
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
-TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
+TEST_CASE("trololo"){}
diff --git a/scripts/linker_stress_test/test.cpp b/scripts/linker_stress_test/test.cpp
index 3ebf1fb..4dbe1c6 100644
--- a/scripts/linker_stress_test/test.cpp
+++ b/scripts/linker_stress_test/test.cpp
@@ -1,11 +1,11 @@
-#include "doctest.h"
-#include "stress.inl"
-#include "stress.inl"
-#include "stress.inl"
-#include "stress.inl"
-#include "stress.inl"
-#include "stress.inl"
-#include "stress.inl"
-#include "stress.inl"
-#include "stress.inl"
-#include "stress.inl"
+#include "doctest.h"
+#include "stress.inl"
+#include "stress.inl"
+#include "stress.inl"
+#include "stress.inl"
+#include "stress.inl"
+#include "stress.inl"
+#include "stress.inl"
+#include "stress.inl"
+#include "stress.inl"
+#include "stress.inl"