summaryrefslogtreecommitdiffstatshomepage
path: root/3rdparty/bx
diff options
context:
space:
mode:
author Miodrag Milanovic <mmicko@gmail.com>2016-05-16 14:17:04 +0200
committer Miodrag Milanovic <mmicko@gmail.com>2016-05-16 14:17:04 +0200
commit71379c56484680a7cf65911fff563be35eb9c976 (patch)
tree7f52c4b90770595a595a4cbc922caf9ce5931001 /3rdparty/bx
parent78421486358513483fb488e0bad4d3f61c7fdbed (diff)
Sync with BGFX (nw)
Diffstat (limited to '3rdparty/bx')
-rw-r--r--3rdparty/bx/3rdparty/UnitTest++/COPYING20
-rw-r--r--3rdparty/bx/3rdparty/UnitTest++/README68
-rw-r--r--3rdparty/bx/3rdparty/UnitTest++/docs/UnitTest++.html260
-rw-r--r--3rdparty/bx/3rdparty/UnitTest++/src/AssertException.cpp34
-rw-r--r--3rdparty/bx/3rdparty/UnitTest++/src/AssertException.h28
-rw-r--r--3rdparty/bx/3rdparty/UnitTest++/src/CheckMacros.h122
-rw-r--r--3rdparty/bx/3rdparty/UnitTest++/src/Checks.cpp50
-rw-r--r--3rdparty/bx/3rdparty/UnitTest++/src/Checks.h158
-rw-r--r--3rdparty/bx/3rdparty/UnitTest++/src/Config.h39
-rw-r--r--3rdparty/bx/3rdparty/UnitTest++/src/CurrentTest.cpp18
-rw-r--r--3rdparty/bx/3rdparty/UnitTest++/src/CurrentTest.h17
-rw-r--r--3rdparty/bx/3rdparty/UnitTest++/src/DeferredTestReporter.cpp28
-rw-r--r--3rdparty/bx/3rdparty/UnitTest++/src/DeferredTestReporter.h29
-rw-r--r--3rdparty/bx/3rdparty/UnitTest++/src/DeferredTestResult.cpp29
-rw-r--r--3rdparty/bx/3rdparty/UnitTest++/src/DeferredTestResult.h32
-rw-r--r--3rdparty/bx/3rdparty/UnitTest++/src/ExecuteTest.h46
-rw-r--r--3rdparty/bx/3rdparty/UnitTest++/src/MemoryOutStream.cpp149
-rw-r--r--3rdparty/bx/3rdparty/UnitTest++/src/MemoryOutStream.h68
-rw-r--r--3rdparty/bx/3rdparty/UnitTest++/src/Posix/SignalTranslator.cpp57
-rw-r--r--3rdparty/bx/3rdparty/UnitTest++/src/Posix/SignalTranslator.h49
-rw-r--r--3rdparty/bx/3rdparty/UnitTest++/src/Posix/TimeHelpers.cpp33
-rw-r--r--3rdparty/bx/3rdparty/UnitTest++/src/Posix/TimeHelpers.h28
-rw-r--r--3rdparty/bx/3rdparty/UnitTest++/src/ReportAssert.cpp11
-rw-r--r--3rdparty/bx/3rdparty/UnitTest++/src/ReportAssert.h10
-rw-r--r--3rdparty/bx/3rdparty/UnitTest++/src/Test.cpp41
-rw-r--r--3rdparty/bx/3rdparty/UnitTest++/src/Test.h34
-rw-r--r--3rdparty/bx/3rdparty/UnitTest++/src/TestDetails.cpp22
-rw-r--r--3rdparty/bx/3rdparty/UnitTest++/src/TestDetails.h24
-rw-r--r--3rdparty/bx/3rdparty/UnitTest++/src/TestList.cpp39
-rw-r--r--3rdparty/bx/3rdparty/UnitTest++/src/TestList.h32
-rw-r--r--3rdparty/bx/3rdparty/UnitTest++/src/TestMacros.h113
-rw-r--r--3rdparty/bx/3rdparty/UnitTest++/src/TestReporter.cpp10
-rw-r--r--3rdparty/bx/3rdparty/UnitTest++/src/TestReporter.h20
-rw-r--r--3rdparty/bx/3rdparty/UnitTest++/src/TestReporterStdout.cpp57
-rw-r--r--3rdparty/bx/3rdparty/UnitTest++/src/TestReporterStdout.h19
-rw-r--r--3rdparty/bx/3rdparty/UnitTest++/src/TestResults.cpp60
-rw-r--r--3rdparty/bx/3rdparty/UnitTest++/src/TestResults.h36
-rw-r--r--3rdparty/bx/3rdparty/UnitTest++/src/TestRunner.cpp76
-rw-r--r--3rdparty/bx/3rdparty/UnitTest++/src/TestRunner.h59
-rw-r--r--3rdparty/bx/3rdparty/UnitTest++/src/TestSuite.h12
-rw-r--r--3rdparty/bx/3rdparty/UnitTest++/src/TimeConstraint.cpp29
-rw-r--r--3rdparty/bx/3rdparty/UnitTest++/src/TimeConstraint.h33
-rw-r--r--3rdparty/bx/3rdparty/UnitTest++/src/TimeHelpers.h7
-rw-r--r--3rdparty/bx/3rdparty/UnitTest++/src/UnitTest++.h18
-rw-r--r--3rdparty/bx/3rdparty/UnitTest++/src/Win32/TimeHelpers.cpp47
-rw-r--r--3rdparty/bx/3rdparty/UnitTest++/src/Win32/TimeHelpers.h48
-rw-r--r--3rdparty/bx/3rdparty/UnitTest++/src/XmlTestReporter.cpp127
-rw-r--r--3rdparty/bx/3rdparty/UnitTest++/src/XmlTestReporter.h34
-rw-r--r--3rdparty/bx/3rdparty/UnitTest++/src/tests/Main.cpp8
-rw-r--r--3rdparty/bx/3rdparty/UnitTest++/src/tests/RecordingReporter.h98
-rw-r--r--3rdparty/bx/3rdparty/UnitTest++/src/tests/ScopedCurrentTest.h37
-rw-r--r--3rdparty/bx/3rdparty/UnitTest++/src/tests/TestAssertHandler.cpp44
-rw-r--r--3rdparty/bx/3rdparty/UnitTest++/src/tests/TestCheckMacros.cpp801
-rw-r--r--3rdparty/bx/3rdparty/UnitTest++/src/tests/TestChecks.cpp293
-rw-r--r--3rdparty/bx/3rdparty/UnitTest++/src/tests/TestCurrentTest.cpp38
-rw-r--r--3rdparty/bx/3rdparty/UnitTest++/src/tests/TestDeferredTestReporter.cpp117
-rw-r--r--3rdparty/bx/3rdparty/UnitTest++/src/tests/TestMemoryOutStream.cpp151
-rw-r--r--3rdparty/bx/3rdparty/UnitTest++/src/tests/TestTest.cpp129
-rw-r--r--3rdparty/bx/3rdparty/UnitTest++/src/tests/TestTestList.cpp50
-rw-r--r--3rdparty/bx/3rdparty/UnitTest++/src/tests/TestTestMacros.cpp212
-rw-r--r--3rdparty/bx/3rdparty/UnitTest++/src/tests/TestTestResults.cpp111
-rw-r--r--3rdparty/bx/3rdparty/UnitTest++/src/tests/TestTestRunner.cpp307
-rw-r--r--3rdparty/bx/3rdparty/UnitTest++/src/tests/TestTestSuite.cpp12
-rw-r--r--3rdparty/bx/3rdparty/UnitTest++/src/tests/TestTimeConstraint.cpp69
-rw-r--r--3rdparty/bx/3rdparty/UnitTest++/src/tests/TestTimeConstraintMacro.cpp65
-rw-r--r--3rdparty/bx/3rdparty/UnitTest++/src/tests/TestUnitTest++.cpp156
-rw-r--r--3rdparty/bx/3rdparty/UnitTest++/src/tests/TestXmlTestReporter.cpp183
-rw-r--r--3rdparty/bx/3rdparty/catch/catch.hpp10485
-rw-r--r--3rdparty/bx/makefile1
-rw-r--r--3rdparty/bx/scripts/genie.lua7
-rw-r--r--3rdparty/bx/scripts/toolchain.lua6
-rw-r--r--3rdparty/bx/scripts/unittest++.lua30
-rw-r--r--3rdparty/bx/tests/main.cpp41
-rw-r--r--3rdparty/bx/tests/test.h5
-rw-r--r--3rdparty/bx/tests/unordered_set_copyctor.cpp1
-rw-r--r--3rdparty/bx/tests/unordered_set_pod.cpp1
-rwxr-xr-x3rdparty/bx/tools/bin/darwin/geniebin463136 -> 467232 bytes
-rwxr-xr-x3rdparty/bx/tools/bin/linux/geniebin437784 -> 441880 bytes
-rw-r--r--3rdparty/bx/tools/bin/windows/genie.exebin443392 -> 445440 bytes
79 files changed, 10504 insertions, 5334 deletions
diff --git a/3rdparty/bx/3rdparty/UnitTest++/COPYING b/3rdparty/bx/3rdparty/UnitTest++/COPYING
deleted file mode 100644
index 9f963085a3f..00000000000
--- a/3rdparty/bx/3rdparty/UnitTest++/COPYING
+++ /dev/null
@@ -1,20 +0,0 @@
-Copyright (c) 2006 Noel Llopis and Charles Nicholson
-
-Permission is hereby granted, free of charge, to any person obtaining
-a copy of this software and associated documentation files (the
-"Software"), to deal in the Software without restriction, including
-without limitation the rights to use, copy, modify, merge, publish,
-distribute, sublicense, and/or sell copies of the Software, and to
-permit persons to whom the Software is furnished to do so, subject to
-the following conditions:
-
-The above copyright notice and this permission notice shall be included
-in all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
-IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
-CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
-TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
-SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
diff --git a/3rdparty/bx/3rdparty/UnitTest++/README b/3rdparty/bx/3rdparty/UnitTest++/README
deleted file mode 100644
index e0a519201ae..00000000000
--- a/3rdparty/bx/3rdparty/UnitTest++/README
+++ /dev/null
@@ -1,68 +0,0 @@
-UnitTest++ README
-Version: v1.4
-Last update: 2008-10-30
-
-UnitTest++ is free software. You may copy, distribute, and modify it under
-the terms of the License contained in the file COPYING distributed
-with this package. This license is the same as the MIT/X Consortium
-license.
-
-See src/tests/TestUnitTest++.cpp for usage.
-
-Authors:
-Noel Llopis (llopis@convexhull.com)
-Charles Nicholson (charles.nicholson@gmail.com)
-
-Contributors:
-Jim Tilander
-Kim Grasman
-Jonathan Jansson
-Dirck Blaskey
-Rory Driscoll
-Dan Lind
-Matt Kimmel -- Submitted with permission from Blue Fang Games
-Anthony Moralez
-Jeff Dixon
-Randy Coulman
-Lieven van der Heide
-
-Release notes:
---------------
-Version 1.4 (2008-10-30)
-- CHECK macros work at arbitrary stack depth from inside TESTs.
-- Remove obsolete TEST_UTILITY macros
-- Predicated test execution (via TestRunner::RunTestsIf)
-- Better exception handling for fixture ctors/dtors.
-- VC6/7/8/9 support
-
-Version 1.3 (2007-4-22)
-- Removed dynamic memory allocations (other than streams)
-- MinGW support
-- Consistent (native) line endings
-- Minor bug fixing
-
-Version 1.2 (2006-10-29)
-- First pass at documentation.
-- More detailed error crash catching in fixtures.
-- Standard streams used for printing objects under check. This should allow the
- use of standard class types such as std::string or other custom classes with
- stream operators to ostream.
-- Standard streams can be optionally compiled off by defining UNITTEST_USE_CUSTOM_STREAMS
- in Config.h
-- Added named test suites
-- Added CHECK_ARRAY2D_CLOSE
-- Posix library name is libUnitTest++.a now
-- Floating point numbers are postfixed with f in the failure reports
-
-Version 1.1 (2006-04-18)
-- CHECK macros do not have side effects even if one of the parameters changes state
-- Removed CHECK_ARRAY_EQUAL (too similar to CHECK_ARRAY_CLOSE)
-- Added local and global time constraints
-- Removed dependencies on strstream
-- Improved Posix signal to exception translator
-- Failing tests are added to Visual Studio's error list
-- Fixed Visual Studio projects to work with spaces in directories
-
-Version 1.0 (2006-03-15)
-- Initial release
-
diff --git a/3rdparty/bx/3rdparty/UnitTest++/docs/UnitTest++.html b/3rdparty/bx/3rdparty/UnitTest++/docs/UnitTest++.html
deleted file mode 100644
index 4af04ec4032..00000000000
--- a/3rdparty/bx/3rdparty/UnitTest++/docs/UnitTest++.html
+++ /dev/null
@@ -1,260 +0,0 @@
-<html>
-<head>
- <title>UnitTest++ in brief</title>
-</head>
-<body>
-<h1>UnitTest++ in brief</h1>
-<h2>Introduction</h2>
-<p>This little document serves as bare-bones documentation for UnitTest++.</p>
-
-<p>For background, goals and license details, see:</p>
-
-<ul>
- <li><a href="http://unittest-cpp.sourceforge.net/">The UnitTest++ home page</a></li>
- <li><a href="http://gamesfromwithin.com/?p=51">Release announcement</a></li>
-</ul>
-
-<p>The documentation, while sparse, aims to be practical, so it should give you enough info to get started using UnitTest++ as fast as possible.</p>
-
-<h2>Building UnitTest++</h2>
-<p>Building UnitTest++ will be specific to each platform and build environment, but it should be straightforward.</p>
-
-<h3>Building with Visual Studio</h3>
-<p>If you are using Visual Studio, go for either of the provided .sln files, depending on version. There are no prefabricated solutions for versions earlier than VS.NET 2003, but we have had reports of people building UnitTest++ with at least VS.NET 2002.</p>
-
-<h3>Building with Make</h3>
-<p>The bundled makefile is written to build with g++. It also needs <code>sed</code> installed in the path, and to be able to use the <code>mv</code> and <code>rm</code> shell commands. The makefile should be usable on most Posix-like platforms.</p>
-
-<p>Do "make all" to generate a library and test executable. A final build step runs all unit tests to make sure that the result works as expected.</p>
-
-<h3>Packaging</h3>
-<p>You'll probably want to keep the generated library in a shared space in source control, so you can reuse it for multiple test projects. A redistributable package of UnitTest++ would consist of the generated library file, and all of the header files in <code>UnitTest++/src/</code> and its per-platform subfolders. The <code>tests</code> directory only contains the unit tests for the library, and need not be included.</p>
-
-<h2>Using UnitTest++</h2>
-<p>The source code for UnitTest++ comes with a full test suite written <em>using</em> UnitTest++. This is a great place to learn techniques for testing. There is one sample .cpp file: <code>UnitTest++/src/tests/TestUnitTest++.cpp</code>. It covers most of UnitTest++'s features in an easy-to-grasp context, so start there if you want a quick overview of typical usage.</p>
-
-<h3>Getting started</h3>
-<p>Listed below is a minimal C++ program to run a failing test through UnitTest++.</p>
-
-<pre>
- // test.cpp
- #include &lt;UnitTest++.h&gt;
-
- TEST(FailSpectacularly)
- {
- CHECK(false);
- }
-
- int main()
- {
- return UnitTest::RunAllTests();
- }
-</pre>
-
-<p><code>UnitTest++.h</code> is a facade header for UnitTest++, so including that should get you all features of the library. All classes and free functions are placed in namespace <code>UnitTest</code>, so you need to either qualify their full names (as with <code>RunAllTests()</code> in the example) or add a <code>using namespace UnitTest;</code> statement in your .cpp files. Note that any mention of UnitTest++ functions and classes in this document assume that the <code>UnitTest</code> namespace has been opened.</p>
-
-<p>Compiling and linking this program with UnitTest++'s static library into an executable, and running it, will produce the following output (details may vary):</p>
-
-<pre>
- .\test.cpp(5): error: Failure in FailSpectacularly: false
- FAILED: 1 out of 1 tests failed (1 failures).
- Test time: 0.00 seconds.
-</pre>
-
-<p>UnitTest++ attempts to report every failure in an IDE-friendly format, depending on platform (e.g. you can double-click it in Visual Studio's error list.) The exit code will be the number of failed tests, so that a failed test run always returns a non-zero exit code.</p>
-
-<h3>Test macros</h3>
-<p>To add a test, simply put the following code in a .cpp file of your choice:</p>
-
-<pre>
- TEST(YourTestName)
- {
- }
-</pre>
-
-<p>The <code>TEST</code> macro contains enough machinery to turn this slightly odd-looking syntax into legal C++, and automatically register the test in a global list. This test list forms the basis of what is executed by <code>RunAllTests()</code>.</p>
-
-<p>If you want to re-use a set of test data for more than one test, or provide setup/teardown for tests, you can use the <code>TEST_FIXTURE</code> macro instead. The macro requires that you pass it a class name that it will instantiate, so any setup and teardown code should be in its constructor and destructor.</p>
-
-<pre>
- struct SomeFixture
- {
- SomeFixture() { /* some setup */ }
- ~SomeFixture() { /* some teardown */ }
-
- int testData;
- };
-
- TEST_FIXTURE(SomeFixture, YourTestName)
- {
- int temp = testData;
- }
-</pre>
-
-<p>Note how members of the fixture are used as if they are a part of the test, since the macro-generated test class derives from the provided fixture class.</p>
-
-<h3>Suite macros</h3>
-<p>Tests can be grouped into suites, using the <code>SUITE</code> macro. A suite serves as a namespace for test names, so that the same test name can be used in two difference contexts.</p>
-
-<pre>
- SUITE(YourSuiteName)
- {
- TEST(YourTestName)
- {
- }
-
- TEST(YourOtherTestName)
- {
- }
- }
-</pre>
-
-<p>This will place the tests into a C++ namespace called <code>YourSuiteName</code>, and make the suite name available to UnitTest++. <code>RunAllTests()</code> can be called for a specific suite name, so you can use this to build named groups of tests to be run together.</p>
-
-<h3>Simple check macros</h3>
-<p>In test cases, we want to check the results of our system under test. UnitTest++ provides a number of check macros that handle comparison and proper failure reporting.</p>
-
-<p>The most basic variety is the boolean <code>CHECK</code> macro:</p>
-
-<pre>
- CHECK(false); // fails
-</pre>
-
-<p>It will fail if the boolean expression evaluates to false.</p>
-
-<p>For equality checks, it's generally better to use <code>CHECK_EQUAL</code>:</p>
-
-<pre>
- CHECK_EQUAL(10, 20); // fails
- CHECK_EQUAL("foo", "bar"); // fails
-</pre>
-
-<p>Note how <code>CHECK_EQUAL</code> is overloaded for C strings, so you don't have to resort to <code>strcmp</code> or similar. There is no facility for case-insensitive comparison or string searches, so you may have to drop down to a plain boolean <code>CHECK</code> with help from the CRT:</p>
-
-<pre>
- CHECK(std::strstr("zaza", "az") != 0); // succeeds
-</pre>
-
-<p>For floating-point comparison, equality <a href="http://www.cygnus-software.com/papers/comparingfloats/comparingfloats.htm">isn't necessarily well-defined</a>, so you should prefer the <code>CHECK_CLOSE</code> macro:</p>
-
-<pre>
- CHECK_CLOSE(3.14, 3.1415, 0.01); // succeeds
-</pre>
-
-<p>All of the macros are tailored to avoid unintended side-effects, for example:</p>
-
-<pre>
- TEST(CheckMacrosHaveNoSideEffects)
- {
- int i = 4;
- CHECK_EQUAL(5, ++i); // succeeds
- CHECK_EQUAL(5, i); // succeeds
- }
-</pre>
-
-<p>The check macros guarantee that the <code>++i</code> expression isn't repeated internally, as demonstrated above.</p>
-
-<h3>Array check macros</h3>
-<p>There is a set of check macros for array comparison as well:</p>
-
-<pre>
- const float oned[2] = { 10, 20 };
- CHECK_ARRAY_EQUAL(oned, oned, 2); // succeeds
- CHECK_ARRAY_CLOSE(oned, oned, 2, 0.00); // succeeds
-
- const float twod[2][3] = { {0, 1, 2}, {2, 3, 4} };
- CHECK_ARRAY2D_CLOSE(twod, twod, 2, 3, 0.00); // succeeds
-</pre>
-
-<p>The array equal macro compares elements using <code>operator==</code>, so <code>CHECK_ARRAY_EQUAL</code> won't work for an array of C strings, for example.</p>
-
-<p>The array close macros are similar to the regular CHECK_CLOSE macro, and are really only useful for scalar types, that can be compared in terms of a difference between two array elements.</p>
-
-<p>Note that the one-dimensional array macros work for <code>std::vector</code> as well, as it can be indexed just as a C array.</p>
-
-<h3>Exception check macros</h3>
-<p>Finally, there's a <code>CHECK_THROW</code> macro, which asserts that its enclosed expression throws the specified type:</p>
-
-<pre>
- struct TestException {};
- CHECK_THROW(throw TestException(), TestException); // succeeds
-</pre>
-
-<p>UnitTest++ natively catches exceptions if your test code doesn't. So if your code under test throws any exception UnitTest++ will fail the test and report either using the <code>what()</code> method for <code>std::exception</code> derivatives or just a plain message for unknown exception types.</p>
-
-<p>Should your test or code raise an irrecoverable error (an Access Violation on Win32, for example, or a signal on Linux), UnitTest++ will attempt to map them to an exception and fail the test, just as for other unhandled exceptions.</p>
-
-<h3>Time constraints</h3>
-<p>UnitTest++ can fail a test if it takes too long to complete, using so-called time constraints.</p>
-
-<p>They come in two flavors; <em>local</em> and <em>global</em> time constraints.</p>
-
-<p>Local time constraints are limited to the current scope, like so:</p>
-
-<pre>
- TEST(YourTimedTest)
- {
- // Lengthy setup...
-
- {
- UNITTEST_TIME_CONSTRAINT(50);
-
- // Do time-critical stuff
- }
-
- // Lengthy teardown...
- }
-</pre>
-
-<p>The test will fail if the "Do time-critical stuff" block takes longer than 50 ms to complete. The time-consuming setup and teardown are not measured, since the time constraint is scope-bound. It's perfectly valid to have multiple local time constraints in the same test, as long as there is only one per block.</p>
-
-<p>A global time constraint, on the other hand, requires that all of the tests in a test run are faster than a specified amount of time. This allows you, when you run a suite of tests, to ask UnitTest++ to fail it entirely if any test exceeds the global constraint. The max time is passed as a parameter to an overload of <code>RunAllTests()</code>.</p>
-
-<p>If you want to use a global time constraint, but have one test that is notoriously slow, you can exempt it from inspection by using the <code>UNITTEST_TIME_CONSTRAINT_EXEMPT</code> macro anywhere inside the test body.</p>
-
-<pre>
- TEST(NotoriouslySlowTest)
- {
- UNITTEST_TIME_CONSTRAINT_EXEMPT();
-
- // Oh boy, this is going to take a while
- ...
- }
-</pre>
-
-<h3>Test runners</h3>
-<p>The <code>RunAllTests()</code> function has an overload that lets you customize the behavior of the runner, such as global time constraints, custom reporters, which suite to run, etc.</p>
-
-<pre>
- int RunAllTests(TestReporter& reporter, TestList const& list, char const* suiteName, int const maxTestTimeInMs);
-</pre>
-
-<p>If you attempt to pass custom parameters to <code>RunAllTests()</code>, note that the <code>list</code> parameter should have the value <code>Test::GetTestList()</code>.</p>
-
-<p>The parameterless <code>RunAllTests()</code> is a simple wrapper for this one, with sensible defaults.</p>
-
-<h3>Example setup</h3>
-<p>How to create a new test project varies depending on your environment, but here are some directions on common file structure and usage.</p>
-
-<p>The general idea is that you keep one <code>Main.cpp</code> file with the entry-point which calls <code>RunAllTests()</code>.</p>
-
-<p>Then you can simply compile and link new .cpp files at will, typically one per test suite.</p>
-
-<pre>
- + ShaverTests/
- |
- +- Main.cpp
- |
- +- TestBrush.cpp
- +- TestEngine.cpp
- +- TestRazor.cpp
-</pre>
-
-<p>Each of the <code>Test*.cpp</code> files will contain one or more <code>TEST</code> macro incantations with the associated test code. There are no source-level dependencies between <code>Main.cpp</code> and <code>Test*.cpp</code>, as the <code>TEST</code> macro handles the registration and setup necessary for <code>RunAllTests()</code> to find all tests compiled into the same final executable.</p>
-
-<p>UnitTest++ does not require this structure, even if this is how the library itself does it. As long as your test project contains one or more <code>TESTs</code> and calls <code>RunAllTests()</code> at one point or another, it will be handled by UnitTest++.</p>
-
-<p>It's common to make the generated executable start as a post-build step, so that merely building your test project will run the tests as well. Since the exit code is the count of failures, a failed test will generally break the build, as most build engines will fail a build if any step returns a non-zero exit code.</p>
-
-</body>
-</html> \ No newline at end of file
diff --git a/3rdparty/bx/3rdparty/UnitTest++/src/AssertException.cpp b/3rdparty/bx/3rdparty/UnitTest++/src/AssertException.cpp
deleted file mode 100644
index 63f556e23fb..00000000000
--- a/3rdparty/bx/3rdparty/UnitTest++/src/AssertException.cpp
+++ /dev/null
@@ -1,34 +0,0 @@
-#include "AssertException.h"
-#include <cstring>
-
-namespace UnitTest {
-
-AssertException::AssertException(char const* description, char const* filename, int lineNumber)
- : m_lineNumber(lineNumber)
-{
- using namespace std;
-
- strcpy(m_description, description);
- strcpy(m_filename, filename);
-}
-
-AssertException::~AssertException() throw()
-{
-}
-
-char const* AssertException::what() const throw()
-{
- return m_description;
-}
-
-char const* AssertException::Filename() const
-{
- return m_filename;
-}
-
-int AssertException::LineNumber() const
-{
- return m_lineNumber;
-}
-
-}
diff --git a/3rdparty/bx/3rdparty/UnitTest++/src/AssertException.h b/3rdparty/bx/3rdparty/UnitTest++/src/AssertException.h
deleted file mode 100644
index e04d450a760..00000000000
--- a/3rdparty/bx/3rdparty/UnitTest++/src/AssertException.h
+++ /dev/null
@@ -1,28 +0,0 @@
-#ifndef UNITTEST_ASSERTEXCEPTION_H
-#define UNITTEST_ASSERTEXCEPTION_H
-
-#include <exception>
-
-
-namespace UnitTest {
-
-class AssertException : public std::exception
-{
-public:
- AssertException(char const* description, char const* filename, int lineNumber);
- virtual ~AssertException() throw();
-
- virtual char const* what() const throw();
-
- char const* Filename() const;
- int LineNumber() const;
-
-private:
- char m_description[512];
- char m_filename[256];
- int m_lineNumber;
-};
-
-}
-
-#endif
diff --git a/3rdparty/bx/3rdparty/UnitTest++/src/CheckMacros.h b/3rdparty/bx/3rdparty/UnitTest++/src/CheckMacros.h
deleted file mode 100644
index 8fbdae77ab4..00000000000
--- a/3rdparty/bx/3rdparty/UnitTest++/src/CheckMacros.h
+++ /dev/null
@@ -1,122 +0,0 @@
-#ifndef UNITTEST_CHECKMACROS_H
-#define UNITTEST_CHECKMACROS_H
-
-#include "Checks.h"
-#include "AssertException.h"
-#include "MemoryOutStream.h"
-#include "TestDetails.h"
-#include "CurrentTest.h"
-
-#ifdef CHECK
- #error UnitTest++ redefines CHECK
-#endif
-
-#ifdef CHECK_EQUAL
- #error UnitTest++ redefines CHECK_EQUAL
-#endif
-
-#ifdef CHECK_CLOSE
- #error UnitTest++ redefines CHECK_CLOSE
-#endif
-
-#ifdef CHECK_ARRAY_EQUAL
- #error UnitTest++ redefines CHECK_ARRAY_EQUAL
-#endif
-
-#ifdef CHECK_ARRAY_CLOSE
- #error UnitTest++ redefines CHECK_ARRAY_CLOSE
-#endif
-
-#ifdef CHECK_ARRAY2D_CLOSE
- #error UnitTest++ redefines CHECK_ARRAY2D_CLOSE
-#endif
-
-#define CHECK(value) \
- do \
- { \
- try { \
- if (!UnitTest::Check(value)) \
- UnitTest::CurrentTest::Results()->OnTestFailure(UnitTest::TestDetails(*UnitTest::CurrentTest::Details(), __LINE__), #value); \
- } \
- catch (...) { \
- UnitTest::CurrentTest::Results()->OnTestFailure(UnitTest::TestDetails(*UnitTest::CurrentTest::Details(), __LINE__), \
- "Unhandled exception in CHECK(" #value ")"); \
- } \
- } while (0)
-
-#define CHECK_EQUAL(expected, actual) \
- do \
- { \
- try { \
- UnitTest::CheckEqual(*UnitTest::CurrentTest::Results(), expected, actual, UnitTest::TestDetails(*UnitTest::CurrentTest::Details(), __LINE__)); \
- } \
- catch (...) { \
- UnitTest::CurrentTest::Results()->OnTestFailure(UnitTest::TestDetails(*UnitTest::CurrentTest::Details(), __LINE__), \
- "Unhandled exception in CHECK_EQUAL(" #expected ", " #actual ")"); \
- } \
- } while (0)
-
-#define CHECK_CLOSE(expected, actual, tolerance) \
- do \
- { \
- try { \
- UnitTest::CheckClose(*UnitTest::CurrentTest::Results(), expected, actual, tolerance, UnitTest::TestDetails(*UnitTest::CurrentTest::Details(), __LINE__)); \
- } \
- catch (...) { \
- UnitTest::CurrentTest::Results()->OnTestFailure(UnitTest::TestDetails(*UnitTest::CurrentTest::Details(), __LINE__), \
- "Unhandled exception in CHECK_CLOSE(" #expected ", " #actual ")"); \
- } \
- } while (0)
-
-#define CHECK_ARRAY_EQUAL(expected, actual, count) \
- do \
- { \
- try { \
- UnitTest::CheckArrayEqual(*UnitTest::CurrentTest::Results(), expected, actual, count, UnitTest::TestDetails(*UnitTest::CurrentTest::Details(), __LINE__)); \
- } \
- catch (...) { \
- UnitTest::CurrentTest::Results()->OnTestFailure(UnitTest::TestDetails(*UnitTest::CurrentTest::Details(), __LINE__), \
- "Unhandled exception in CHECK_ARRAY_EQUAL(" #expected ", " #actual ")"); \
- } \
- } while (0)
-
-#define CHECK_ARRAY_CLOSE(expected, actual, count, tolerance) \
- do \
- { \
- try { \
- UnitTest::CheckArrayClose(*UnitTest::CurrentTest::Results(), expected, actual, count, tolerance, UnitTest::TestDetails(*UnitTest::CurrentTest::Details(), __LINE__)); \
- } \
- catch (...) { \
- UnitTest::CurrentTest::Results()->OnTestFailure(UnitTest::TestDetails(*UnitTest::CurrentTest::Details(), __LINE__), \
- "Unhandled exception in CHECK_ARRAY_CLOSE(" #expected ", " #actual ")"); \
- } \
- } while (0)
-
-#define CHECK_ARRAY2D_CLOSE(expected, actual, rows, columns, tolerance) \
- do \
- { \
- try { \
- UnitTest::CheckArray2DClose(*UnitTest::CurrentTest::Results(), expected, actual, rows, columns, tolerance, UnitTest::TestDetails(*UnitTest::CurrentTest::Details(), __LINE__)); \
- } \
- catch (...) { \
- UnitTest::CurrentTest::Results()->OnTestFailure(UnitTest::TestDetails(*UnitTest::CurrentTest::Details(), __LINE__), \
- "Unhandled exception in CHECK_ARRAY_CLOSE(" #expected ", " #actual ")"); \
- } \
- } while (0)
-
-
-#define CHECK_THROW(expression, ExpectedExceptionType) \
- do \
- { \
- bool caught_ = false; \
- try { expression; } \
- catch (ExpectedExceptionType const&) { caught_ = true; } \
- catch (...) {} \
- if (!caught_) \
- UnitTest::CurrentTest::Results()->OnTestFailure(UnitTest::TestDetails(*UnitTest::CurrentTest::Details(), __LINE__), "Expected exception: \"" #ExpectedExceptionType "\" not thrown"); \
- } while(0)
-
-#define CHECK_ASSERT(expression) \
- CHECK_THROW(expression, UnitTest::AssertException);
-
-#endif
diff --git a/3rdparty/bx/3rdparty/UnitTest++/src/Checks.cpp b/3rdparty/bx/3rdparty/UnitTest++/src/Checks.cpp
deleted file mode 100644
index 2d0951933ae..00000000000
--- a/3rdparty/bx/3rdparty/UnitTest++/src/Checks.cpp
+++ /dev/null
@@ -1,50 +0,0 @@
-#include "Checks.h"
-#include <cstring>
-
-namespace UnitTest {
-
-namespace {
-
-void CheckStringsEqual(TestResults& results, char const* expected, char const* actual,
- TestDetails const& details)
-{
- using namespace std;
-
- if (strcmp(expected, actual))
- {
- UnitTest::MemoryOutStream stream;
- stream << "Expected " << expected << " but was " << actual;
-
- results.OnTestFailure(details, stream.GetText());
- }
-}
-
-}
-
-
-void CheckEqual(TestResults& results, char const* expected, char const* actual,
- TestDetails const& details)
-{
- CheckStringsEqual(results, expected, actual, details);
-}
-
-void CheckEqual(TestResults& results, char* expected, char* actual,
- TestDetails const& details)
-{
- CheckStringsEqual(results, expected, actual, details);
-}
-
-void CheckEqual(TestResults& results, char* expected, char const* actual,
- TestDetails const& details)
-{
- CheckStringsEqual(results, expected, actual, details);
-}
-
-void CheckEqual(TestResults& results, char const* expected, char* actual,
- TestDetails const& details)
-{
- CheckStringsEqual(results, expected, actual, details);
-}
-
-
-}
diff --git a/3rdparty/bx/3rdparty/UnitTest++/src/Checks.h b/3rdparty/bx/3rdparty/UnitTest++/src/Checks.h
deleted file mode 100644
index 00900841713..00000000000
--- a/3rdparty/bx/3rdparty/UnitTest++/src/Checks.h
+++ /dev/null
@@ -1,158 +0,0 @@
-#ifndef UNITTEST_CHECKS_H
-#define UNITTEST_CHECKS_H
-
-#include "Config.h"
-#include "TestResults.h"
-#include "MemoryOutStream.h"
-
-namespace UnitTest {
-
-
-template< typename Value >
-bool Check(Value const value)
-{
- return !!value; // doing double negative to avoid silly VS warnings
-}
-
-
-template< typename Expected, typename Actual >
-void CheckEqual(TestResults& results, Expected const& expected, Actual const& actual, TestDetails const& details)
-{
- if (!(expected == actual))
- {
- UnitTest::MemoryOutStream stream;
- stream << "Expected " << expected << " but was " << actual;
-
- results.OnTestFailure(details, stream.GetText());
- }
-}
-
-void CheckEqual(TestResults& results, char const* expected, char const* actual, TestDetails const& details);
-
-void CheckEqual(TestResults& results, char* expected, char* actual, TestDetails const& details);
-
-void CheckEqual(TestResults& results, char* expected, char const* actual, TestDetails const& details);
-
-void CheckEqual(TestResults& results, char const* expected, char* actual, TestDetails const& details);
-
-template< typename Expected, typename Actual, typename Tolerance >
-bool AreClose(Expected const& expected, Actual const& actual, Tolerance const& tolerance)
-{
- return (actual >= (expected - tolerance)) && (actual <= (expected + tolerance));
-}
-
-template< typename Expected, typename Actual, typename Tolerance >
-void CheckClose(TestResults& results, Expected const& expected, Actual const& actual, Tolerance const& tolerance,
- TestDetails const& details)
-{
- if (!AreClose(expected, actual, tolerance))
- {
- UnitTest::MemoryOutStream stream;
- stream << "Expected " << expected << " +/- " << tolerance << " but was " << actual;
-
- results.OnTestFailure(details, stream.GetText());
- }
-}
-
-
-template< typename Expected, typename Actual >
-void CheckArrayEqual(TestResults& results, Expected const& expected, Actual const& actual,
- int const count, TestDetails const& details)
-{
- bool equal = true;
- for (int i = 0; i < count; ++i)
- equal &= (expected[i] == actual[i]);
-
- if (!equal)
- {
- UnitTest::MemoryOutStream stream;
-
- stream << "Expected [ ";
-
- for (int expectedIndex = 0; expectedIndex < count; ++expectedIndex)
- stream << expected[expectedIndex] << " ";
-
- stream << "] but was [ ";
-
- for (int actualIndex = 0; actualIndex < count; ++actualIndex)
- stream << actual[actualIndex] << " ";
-
- stream << "]";
-
- results.OnTestFailure(details, stream.GetText());
- }
-}
-
-template< typename Expected, typename Actual, typename Tolerance >
-bool ArrayAreClose(Expected const& expected, Actual const& actual, int const count, Tolerance const& tolerance)
-{
- bool equal = true;
- for (int i = 0; i < count; ++i)
- equal &= AreClose(expected[i], actual[i], tolerance);
- return equal;
-}
-
-template< typename Expected, typename Actual, typename Tolerance >
-void CheckArrayClose(TestResults& results, Expected const& expected, Actual const& actual,
- int const count, Tolerance const& tolerance, TestDetails const& details)
-{
- bool equal = ArrayAreClose(expected, actual, count, tolerance);
-
- if (!equal)
- {
- UnitTest::MemoryOutStream stream;
-
- stream << "Expected [ ";
- for (int expectedIndex = 0; expectedIndex < count; ++expectedIndex)
- stream << expected[expectedIndex] << " ";
- stream << "] +/- " << tolerance << " but was [ ";
-
- for (int actualIndex = 0; actualIndex < count; ++actualIndex)
- stream << actual[actualIndex] << " ";
- stream << "]";
-
- results.OnTestFailure(details, stream.GetText());
- }
-}
-
-template< typename Expected, typename Actual, typename Tolerance >
-void CheckArray2DClose(TestResults& results, Expected const& expected, Actual const& actual,
- int const rows, int const columns, Tolerance const& tolerance, TestDetails const& details)
-{
- bool equal = true;
- for (int i = 0; i < rows; ++i)
- equal &= ArrayAreClose(expected[i], actual[i], columns, tolerance);
-
- if (!equal)
- {
- UnitTest::MemoryOutStream stream;
-
- stream << "Expected [ ";
-
- for (int expectedRow = 0; expectedRow < rows; ++expectedRow)
- {
- stream << "[ ";
- for (int expectedColumn = 0; expectedColumn < columns; ++expectedColumn)
- stream << expected[expectedRow][expectedColumn] << " ";
- stream << "] ";
- }
-
- stream << "] +/- " << tolerance << " but was [ ";
-
- for (int actualRow = 0; actualRow < rows; ++actualRow)
- {
- stream << "[ ";
- for (int actualColumn = 0; actualColumn < columns; ++actualColumn)
- stream << actual[actualRow][actualColumn] << " ";
- stream << "] ";
- }
-
- stream << "]";
-
- results.OnTestFailure(details, stream.GetText());
- }
-}
-
-}
-
-#endif
diff --git a/3rdparty/bx/3rdparty/UnitTest++/src/Config.h b/3rdparty/bx/3rdparty/UnitTest++/src/Config.h
deleted file mode 100644
index 200833e9eae..00000000000
--- a/3rdparty/bx/3rdparty/UnitTest++/src/Config.h
+++ /dev/null
@@ -1,39 +0,0 @@
-#ifndef UNITTEST_CONFIG_H
-#define UNITTEST_CONFIG_H
-
-// Standard defines documented here: http://predef.sourceforge.net
-
-#if defined(_MSC_VER)
-# pragma warning(disable:4127) // conditional expression is constant
-# pragma warning(disable:4702) // unreachable code
-# pragma warning(disable:4722) // destructor never returns, potential memory leak
-
-# if (_MSC_VER == 1200) // VC6
-# pragma warning(disable:4786)
-# pragma warning(disable:4290)
-# endif
-#endif
-
-#if defined(unix) \
- || defined(__unix__) \
- || defined(__unix) \
- || defined(linux) \
- || defined(__APPLE__) \
- || defined(__NetBSD__) \
- || defined(__OpenBSD__) \
- || defined(__FreeBSD__) \
- || defined(__native_client__) \
- || defined(__riscv)
-# define UNITTEST_POSIX
-#endif
-
-#if defined(__MINGW32__)
-# define UNITTEST_MINGW
-#endif
-
-// by default, MemoryOutStream is implemented in terms of std::ostringstream, which can be expensive.
-// uncomment this line to use the custom MemoryOutStream (no deps on std::ostringstream).
-
-//#define UNITTEST_USE_CUSTOM_STREAMS
-
-#endif
diff --git a/3rdparty/bx/3rdparty/UnitTest++/src/CurrentTest.cpp b/3rdparty/bx/3rdparty/UnitTest++/src/CurrentTest.cpp
deleted file mode 100644
index ad8d9af275d..00000000000
--- a/3rdparty/bx/3rdparty/UnitTest++/src/CurrentTest.cpp
+++ /dev/null
@@ -1,18 +0,0 @@
-#include "CurrentTest.h"
-#include <cstddef>
-
-namespace UnitTest {
-
-TestResults*& CurrentTest::Results()
-{
- static TestResults* testResults = NULL;
- return testResults;
-}
-
-const TestDetails*& CurrentTest::Details()
-{
- static const TestDetails* testDetails = NULL;
- return testDetails;
-}
-
-}
diff --git a/3rdparty/bx/3rdparty/UnitTest++/src/CurrentTest.h b/3rdparty/bx/3rdparty/UnitTest++/src/CurrentTest.h
deleted file mode 100644
index 9e9d07a510e..00000000000
--- a/3rdparty/bx/3rdparty/UnitTest++/src/CurrentTest.h
+++ /dev/null
@@ -1,17 +0,0 @@
-#ifndef UNITTEST_CURRENTTESTRESULTS_H
-#define UNITTEST_CURRENTTESTRESULTS_H
-
-namespace UnitTest {
-
-class TestResults;
-class TestDetails;
-
-namespace CurrentTest
-{
- TestResults*& Results();
- const TestDetails*& Details();
-}
-
-}
-
-#endif
diff --git a/3rdparty/bx/3rdparty/UnitTest++/src/DeferredTestReporter.cpp b/3rdparty/bx/3rdparty/UnitTest++/src/DeferredTestReporter.cpp
deleted file mode 100644
index ae77b033719..00000000000
--- a/3rdparty/bx/3rdparty/UnitTest++/src/DeferredTestReporter.cpp
+++ /dev/null
@@ -1,28 +0,0 @@
-#include "DeferredTestReporter.h"
-#include "TestDetails.h"
-
-using namespace UnitTest;
-
-void DeferredTestReporter::ReportTestStart(TestDetails const& details)
-{
- m_results.push_back(DeferredTestResult(details.suiteName, details.testName));
-}
-
-void DeferredTestReporter::ReportFailure(TestDetails const& details, char const* failure)
-{
- DeferredTestResult& r = m_results.back();
- r.failed = true;
- r.failures.push_back(DeferredTestResult::Failure(details.lineNumber, failure));
- r.failureFile = details.filename;
-}
-
-void DeferredTestReporter::ReportTestFinish(TestDetails const&, float secondsElapsed)
-{
- DeferredTestResult& r = m_results.back();
- r.timeElapsed = secondsElapsed;
-}
-
-DeferredTestReporter::DeferredTestResultList& DeferredTestReporter::GetResults()
-{
- return m_results;
-}
diff --git a/3rdparty/bx/3rdparty/UnitTest++/src/DeferredTestReporter.h b/3rdparty/bx/3rdparty/UnitTest++/src/DeferredTestReporter.h
deleted file mode 100644
index 615a24e3b72..00000000000
--- a/3rdparty/bx/3rdparty/UnitTest++/src/DeferredTestReporter.h
+++ /dev/null
@@ -1,29 +0,0 @@
-#ifndef UNITTEST_DEFERREDTESTREPORTER_H
-#define UNITTEST_DEFERREDTESTREPORTER_H
-
-#include "TestReporter.h"
-#include "DeferredTestResult.h"
-#include "Config.h"
-
-#include <vector>
-
-namespace UnitTest
-{
-
-class DeferredTestReporter : public TestReporter
-{
-public:
- virtual void ReportTestStart(TestDetails const& details);
- virtual void ReportFailure(TestDetails const& details, char const* failure);
- virtual void ReportTestFinish(TestDetails const& details, float secondsElapsed);
-
- typedef std::vector< DeferredTestResult > DeferredTestResultList;
- DeferredTestResultList& GetResults();
-
-private:
- DeferredTestResultList m_results;
-};
-
-}
-
-#endif
diff --git a/3rdparty/bx/3rdparty/UnitTest++/src/DeferredTestResult.cpp b/3rdparty/bx/3rdparty/UnitTest++/src/DeferredTestResult.cpp
deleted file mode 100644
index 76c90fe1ce3..00000000000
--- a/3rdparty/bx/3rdparty/UnitTest++/src/DeferredTestResult.cpp
+++ /dev/null
@@ -1,29 +0,0 @@
-#include "DeferredTestResult.h"
-#include "Config.h"
-
-namespace UnitTest
-{
-
-DeferredTestResult::DeferredTestResult()
- : suiteName("")
- , testName("")
- , failureFile("")
- , timeElapsed(0.0f)
- , failed(false)
-{
-}
-
-DeferredTestResult::DeferredTestResult(char const* suite, char const* test)
- : suiteName(suite)
- , testName(test)
- , failureFile("")
- , timeElapsed(0.0f)
- , failed(false)
-{
-}
-
-DeferredTestResult::~DeferredTestResult()
-{
-}
-
-}
diff --git a/3rdparty/bx/3rdparty/UnitTest++/src/DeferredTestResult.h b/3rdparty/bx/3rdparty/UnitTest++/src/DeferredTestResult.h
deleted file mode 100644
index d0a1dab1abe..00000000000
--- a/3rdparty/bx/3rdparty/UnitTest++/src/DeferredTestResult.h
+++ /dev/null
@@ -1,32 +0,0 @@
-#ifndef UNITTEST_DEFERREDTESTRESULT_H
-#define UNITTEST_DEFERREDTESTRESULT_H
-
-#include "Config.h"
-
-#include <string>
-#include <vector>
-
-namespace UnitTest
-{
-
-struct DeferredTestResult
-{
- DeferredTestResult();
- DeferredTestResult(char const* suite, char const* test);
- ~DeferredTestResult();
-
- std::string suiteName;
- std::string testName;
- std::string failureFile;
-
- typedef std::pair< int, std::string > Failure;
- typedef std::vector< Failure > FailureVec;
- FailureVec failures;
-
- float timeElapsed;
- bool failed;
-};
-
-}
-
-#endif //UNITTEST_DEFERREDTESTRESULT_H
diff --git a/3rdparty/bx/3rdparty/UnitTest++/src/ExecuteTest.h b/3rdparty/bx/3rdparty/UnitTest++/src/ExecuteTest.h
deleted file mode 100644
index a00d4c5757e..00000000000
--- a/3rdparty/bx/3rdparty/UnitTest++/src/ExecuteTest.h
+++ /dev/null
@@ -1,46 +0,0 @@
-#ifndef UNITTEST_EXECUTE_TEST_H
-#define UNITTEST_EXECUTE_TEST_H
-
-#include "TestDetails.h"
-#include "MemoryOutStream.h"
-#include "AssertException.h"
-#include "CurrentTest.h"
-
-#ifdef UNITTEST_POSIX
- #include "Posix/SignalTranslator.h"
-#endif
-
-namespace UnitTest {
-
-template< typename T >
-void ExecuteTest(T& testObject, TestDetails const& details)
-{
- CurrentTest::Details() = &details;
-
- try
- {
-#ifdef UNITTEST_POSIX
- UNITTEST_THROW_SIGNALS
-#endif
- testObject.RunImpl();
- }
- catch (AssertException const& e)
- {
- CurrentTest::Results()->OnTestFailure(
- TestDetails(details.testName, details.suiteName, e.Filename(), e.LineNumber()), e.what());
- }
- catch (std::exception const& e)
- {
- MemoryOutStream stream;
- stream << "Unhandled exception: " << e.what();
- CurrentTest::Results()->OnTestFailure(details, stream.GetText());
- }
- catch (...)
- {
- CurrentTest::Results()->OnTestFailure(details, "Unhandled exception: Crash!");
- }
-}
-
-}
-
-#endif
diff --git a/3rdparty/bx/3rdparty/UnitTest++/src/MemoryOutStream.cpp b/3rdparty/bx/3rdparty/UnitTest++/src/MemoryOutStream.cpp
deleted file mode 100644
index 67a3e372ba0..00000000000
--- a/3rdparty/bx/3rdparty/UnitTest++/src/MemoryOutStream.cpp
+++ /dev/null
@@ -1,149 +0,0 @@
-#include "MemoryOutStream.h"
-
-#ifndef UNITTEST_USE_CUSTOM_STREAMS
-
-
-namespace UnitTest {
-
-char const* MemoryOutStream::GetText() const
-{
- m_text = this->str();
- return m_text.c_str();
-}
-
-
-}
-
-
-#else
-
-
-#include <cstring>
-#include <cstdio>
-
-namespace UnitTest {
-
-namespace {
-
-template<typename ValueType>
-void FormatToStream(MemoryOutStream& stream, char const* format, ValueType const& value)
-{
- using namespace std;
-
- char txt[32];
- sprintf(txt, format, value);
- stream << txt;
-}
-
-int RoundUpToMultipleOfPow2Number (int n, int pow2Number)
-{
- return (n + (pow2Number - 1)) & ~(pow2Number - 1);
-}
-
-}
-
-
-MemoryOutStream::MemoryOutStream(int const size)
- : m_capacity (0)
- , m_buffer (0)
-
-{
- GrowBuffer(size);
-}
-
-MemoryOutStream::~MemoryOutStream()
-{
- delete [] m_buffer;
-}
-
-char const* MemoryOutStream::GetText() const
-{
- return m_buffer;
-}
-
-MemoryOutStream& MemoryOutStream::operator << (char const* txt)
-{
- using namespace std;
-
- int const bytesLeft = m_capacity - (int)strlen(m_buffer);
- int const bytesRequired = (int)strlen(txt) + 1;
-
- if (bytesRequired > bytesLeft)
- {
- int const requiredCapacity = bytesRequired + m_capacity - bytesLeft;
- GrowBuffer(requiredCapacity);
- }
-
- strcat(m_buffer, txt);
- return *this;
-}
-
-MemoryOutStream& MemoryOutStream::operator << (int const n)
-{
- FormatToStream(*this, "%i", n);
- return *this;
-}
-
-MemoryOutStream& MemoryOutStream::operator << (long const n)
-{
- FormatToStream(*this, "%li", n);
- return *this;
-}
-
-MemoryOutStream& MemoryOutStream::operator << (unsigned long const n)
-{
- FormatToStream(*this, "%lu", n);
- return *this;
-}
-
-MemoryOutStream& MemoryOutStream::operator << (float const f)
-{
- FormatToStream(*this, "%ff", f);
- return *this;
-}
-
-MemoryOutStream& MemoryOutStream::operator << (void const* p)
-{
- FormatToStream(*this, "%p", p);
- return *this;
-}
-
-MemoryOutStream& MemoryOutStream::operator << (unsigned int const s)
-{
- FormatToStream(*this, "%u", s);
- return *this;
-}
-
-MemoryOutStream& MemoryOutStream::operator <<(double const d)
-{
- FormatToStream(*this, "%f", d);
- return *this;
-}
-
-int MemoryOutStream::GetCapacity() const
-{
- return m_capacity;
-}
-
-
-void MemoryOutStream::GrowBuffer(int const desiredCapacity)
-{
- int const newCapacity = RoundUpToMultipleOfPow2Number(desiredCapacity, GROW_CHUNK_SIZE);
-
- using namespace std;
-
- char* buffer = new char[newCapacity];
- if (m_buffer)
- strcpy(buffer, m_buffer);
- else
- strcpy(buffer, "");
-
- delete [] m_buffer;
- m_buffer = buffer;
- m_capacity = newCapacity;
-}
-
-}
-
-
-#endif
diff --git a/3rdparty/bx/3rdparty/UnitTest++/src/MemoryOutStream.h b/3rdparty/bx/3rdparty/UnitTest++/src/MemoryOutStream.h
deleted file mode 100644
index 37a4afd49ad..00000000000
--- a/3rdparty/bx/3rdparty/UnitTest++/src/MemoryOutStream.h
+++ /dev/null
@@ -1,68 +0,0 @@
-#ifndef UNITTEST_MEMORYOUTSTREAM_H
-#define UNITTEST_MEMORYOUTSTREAM_H
-
-#include "Config.h"
-
-#ifndef UNITTEST_USE_CUSTOM_STREAMS
-
-#include <sstream>
-
-namespace UnitTest
-{
-
-class MemoryOutStream : public std::ostringstream
-{
-public:
- MemoryOutStream() {}
- ~MemoryOutStream() {}
- char const* GetText() const;
-
-private:
- MemoryOutStream(MemoryOutStream const&);
- void operator =(MemoryOutStream const&);
-
- mutable std::string m_text;
-};
-
-}
-
-#else
-
-#include <cstddef>
-
-namespace UnitTest
-{
-
-class MemoryOutStream
-{
-public:
- explicit MemoryOutStream(int const size = 256);
- ~MemoryOutStream();
-
- char const* GetText() const;
-
- MemoryOutStream& operator << (char const* txt);
- MemoryOutStream& operator << (int n);
- MemoryOutStream& operator << (long n);
- MemoryOutStream& operator << (unsigned long n);
- MemoryOutStream& operator << (float f);
- MemoryOutStream& operator << (double d);
- MemoryOutStream& operator << (void const* p);
- MemoryOutStream& operator << (unsigned int s);
-
- enum { GROW_CHUNK_SIZE = 32 };
- int GetCapacity() const;
-
-private:
- void operator= (MemoryOutStream const&);
- void GrowBuffer(int capacity);
-
- int m_capacity;
- char* m_buffer;
-};
-
-}
-
-#endif
-
-#endif
diff --git a/3rdparty/bx/3rdparty/UnitTest++/src/Posix/SignalTranslator.cpp b/3rdparty/bx/3rdparty/UnitTest++/src/Posix/SignalTranslator.cpp
deleted file mode 100644
index d0415addacb..00000000000
--- a/3rdparty/bx/3rdparty/UnitTest++/src/Posix/SignalTranslator.cpp
+++ /dev/null
@@ -1,57 +0,0 @@
-#include "SignalTranslator.h"
-
-namespace UnitTest {
-
-#if defined(__native_client__)
-SignalTranslator::SignalTranslator()
-{
-}
-
-SignalTranslator::~SignalTranslator()
-{
-}
-#else
-
-sigjmp_buf* SignalTranslator::s_jumpTarget = 0;
-
-namespace {
-
-void SignalHandler(int sig)
-{
- siglongjmp(*SignalTranslator::s_jumpTarget, sig );
-}
-
-}
-
-
-SignalTranslator::SignalTranslator()
-{
- m_oldJumpTarget = s_jumpTarget;
- s_jumpTarget = &m_currentJumpTarget;
-
- struct sigaction action;
- action.sa_flags = 0;
- action.sa_handler = SignalHandler;
- sigemptyset( &action.sa_mask );
-
- sigaction( SIGSEGV, &action, &m_old_SIGSEGV_action );
- sigaction( SIGFPE , &action, &m_old_SIGFPE_action );
- sigaction( SIGTRAP, &action, &m_old_SIGTRAP_action );
- sigaction( SIGBUS , &action, &m_old_SIGBUS_action );
- sigaction( SIGILL , &action, &m_old_SIGBUS_action );
-}
-
-SignalTranslator::~SignalTranslator()
-{
- sigaction( SIGILL , &m_old_SIGBUS_action , 0 );
- sigaction( SIGBUS , &m_old_SIGBUS_action , 0 );
- sigaction( SIGTRAP, &m_old_SIGTRAP_action, 0 );
- sigaction( SIGFPE , &m_old_SIGFPE_action , 0 );
- sigaction( SIGSEGV, &m_old_SIGSEGV_action, 0 );
-
- s_jumpTarget = m_oldJumpTarget;
-}
-
-#endif // defined(__native_client__)
-
-}
diff --git a/3rdparty/bx/3rdparty/UnitTest++/src/Posix/SignalTranslator.h b/3rdparty/bx/3rdparty/UnitTest++/src/Posix/SignalTranslator.h
deleted file mode 100644
index 5de677e6bd6..00000000000
--- a/3rdparty/bx/3rdparty/UnitTest++/src/Posix/SignalTranslator.h
+++ /dev/null
@@ -1,49 +0,0 @@
-#ifndef UNITTEST_SIGNALTRANSLATOR_H
-#define UNITTEST_SIGNALTRANSLATOR_H
-
-#include <setjmp.h>
-#include <signal.h>
-
-namespace UnitTest {
-
-class SignalTranslator
-{
-public:
- SignalTranslator();
- ~SignalTranslator();
-
-#if defined(__native_client__)
-#else
- static sigjmp_buf* s_jumpTarget;
-
-private:
- sigjmp_buf m_currentJumpTarget;
- sigjmp_buf* m_oldJumpTarget;
-
- struct sigaction m_old_SIGFPE_action;
- struct sigaction m_old_SIGTRAP_action;
- struct sigaction m_old_SIGSEGV_action;
- struct sigaction m_old_SIGBUS_action;
-// struct sigaction m_old_SIGABRT_action;
-// struct sigaction m_old_SIGALRM_action;
-#endif // defined(__native_client__)
-};
-
-#if !defined(__GNUC__) && !defined(__clang__)
-# define UNITTEST_EXTENSION
-#else
-# define UNITTEST_EXTENSION __extension__
-#endif
-
-#if defined(__native_client__)
-# define UNITTEST_THROW_SIGNALS
-#else
-# define UNITTEST_THROW_SIGNALS \
- UnitTest::SignalTranslator sig; \
- if (UNITTEST_EXTENSION sigsetjmp(*UnitTest::SignalTranslator::s_jumpTarget, 1) != 0) \
- throw ("Unhandled system exception");
-#endif // defined(__native_client__)
-
-}
-
-#endif
diff --git a/3rdparty/bx/3rdparty/UnitTest++/src/Posix/TimeHelpers.cpp b/3rdparty/bx/3rdparty/UnitTest++/src/Posix/TimeHelpers.cpp
deleted file mode 100644
index 65c63937a0e..00000000000
--- a/3rdparty/bx/3rdparty/UnitTest++/src/Posix/TimeHelpers.cpp
+++ /dev/null
@@ -1,33 +0,0 @@
-#include "TimeHelpers.h"
-#include <unistd.h>
-
-namespace UnitTest {
-
-Timer::Timer()
-{
- m_startTime.tv_sec = 0;
- m_startTime.tv_usec = 0;
-}
-
-void Timer::Start()
-{
- gettimeofday(&m_startTime, 0);
-}
-
-double Timer::GetTimeInMs() const
-{
- struct timeval currentTime;
- gettimeofday(&currentTime, 0);
-
- double const dsecs = currentTime.tv_sec - m_startTime.tv_sec;
- double const dus = currentTime.tv_usec - m_startTime.tv_usec;
-
- return (dsecs * 1000.0) + (dus / 1000.0);
-}
-
-void TimeHelpers::SleepMs(int ms)
-{
- usleep(ms * 1000);
-}
-
-}
diff --git a/3rdparty/bx/3rdparty/UnitTest++/src/Posix/TimeHelpers.h b/3rdparty/bx/3rdparty/UnitTest++/src/Posix/TimeHelpers.h
deleted file mode 100644
index 528e62e818e..00000000000
--- a/3rdparty/bx/3rdparty/UnitTest++/src/Posix/TimeHelpers.h
+++ /dev/null
@@ -1,28 +0,0 @@
-#ifndef UNITTEST_TIMEHELPERS_H
-#define UNITTEST_TIMEHELPERS_H
-
-#include <sys/time.h>
-
-namespace UnitTest {
-
-class Timer
-{
-public:
- Timer();
- void Start();
- double GetTimeInMs() const;
-
-private:
- struct timeval m_startTime;
-};
-
-
-namespace TimeHelpers
-{
-void SleepMs (int ms);
-}
-
-
-}
-
-#endif
diff --git a/3rdparty/bx/3rdparty/UnitTest++/src/ReportAssert.cpp b/3rdparty/bx/3rdparty/UnitTest++/src/ReportAssert.cpp
deleted file mode 100644
index c91f4f6e950..00000000000
--- a/3rdparty/bx/3rdparty/UnitTest++/src/ReportAssert.cpp
+++ /dev/null
@@ -1,11 +0,0 @@
-#include "ReportAssert.h"
-#include "AssertException.h"
-
-namespace UnitTest {
-
-void ReportAssert(char const* description, char const* filename, int lineNumber)
-{
- throw AssertException(description, filename, lineNumber);
-}
-
-}
diff --git a/3rdparty/bx/3rdparty/UnitTest++/src/ReportAssert.h b/3rdparty/bx/3rdparty/UnitTest++/src/ReportAssert.h
deleted file mode 100644
index d4dd864173c..00000000000
--- a/3rdparty/bx/3rdparty/UnitTest++/src/ReportAssert.h
+++ /dev/null
@@ -1,10 +0,0 @@
-#ifndef UNITTEST_ASSERT_H
-#define UNITTEST_ASSERT_H
-
-namespace UnitTest {
-
-void ReportAssert(char const* description, char const* filename, int lineNumber);
-
-}
-
-#endif
diff --git a/3rdparty/bx/3rdparty/UnitTest++/src/Test.cpp b/3rdparty/bx/3rdparty/UnitTest++/src/Test.cpp
deleted file mode 100644
index bc9cb3df076..00000000000
--- a/3rdparty/bx/3rdparty/UnitTest++/src/Test.cpp
+++ /dev/null
@@ -1,41 +0,0 @@
-#include "Config.h"
-#include "Test.h"
-#include "TestList.h"
-#include "TestResults.h"
-#include "AssertException.h"
-#include "MemoryOutStream.h"
-#include "ExecuteTest.h"
-
-#ifdef UNITTEST_POSIX
- #include "Posix/SignalTranslator.h"
-#endif
-
-namespace UnitTest {
-
-TestList& Test::GetTestList()
-{
- static TestList s_list;
- return s_list;
-}
-
-Test::Test(char const* testName, char const* suiteName, char const* filename, int lineNumber)
- : m_details(testName, suiteName, filename, lineNumber)
- , next(0)
- , m_timeConstraintExempt(false)
-{
-}
-
-Test::~Test()
-{
-}
-
-void Test::Run()
-{
- ExecuteTest(*this, m_details);
-}
-
-void Test::RunImpl() const
-{
-}
-
-}
diff --git a/3rdparty/bx/3rdparty/UnitTest++/src/Test.h b/3rdparty/bx/3rdparty/UnitTest++/src/Test.h
deleted file mode 100644
index 91026b6e3c9..00000000000
--- a/3rdparty/bx/3rdparty/UnitTest++/src/Test.h
+++ /dev/null
@@ -1,34 +0,0 @@
-#ifndef UNITTEST_TEST_H
-#define UNITTEST_TEST_H
-
-#include "TestDetails.h"
-
-namespace UnitTest {
-
-class TestResults;
-class TestList;
-
-class Test
-{
-public:
- explicit Test(char const* testName, char const* suiteName = "DefaultSuite", char const* filename = "", int lineNumber = 0);
- virtual ~Test();
- void Run();
-
- TestDetails const m_details;
- Test* next;
- mutable bool m_timeConstraintExempt;
-
- static TestList& GetTestList();
-
- virtual void RunImpl() const;
-
-private:
- Test(Test const&);
- Test& operator =(Test const&);
-};
-
-
-}
-
-#endif
diff --git a/3rdparty/bx/3rdparty/UnitTest++/src/TestDetails.cpp b/3rdparty/bx/3rdparty/UnitTest++/src/TestDetails.cpp
deleted file mode 100644
index a13a168625d..00000000000
--- a/3rdparty/bx/3rdparty/UnitTest++/src/TestDetails.cpp
+++ /dev/null
@@ -1,22 +0,0 @@
-#include "TestDetails.h"
-
-namespace UnitTest {
-
-TestDetails::TestDetails(char const* testName_, char const* suiteName_, char const* filename_, int lineNumber_)
- : suiteName(suiteName_)
- , testName(testName_)
- , filename(filename_)
- , lineNumber(lineNumber_)
-{
-}
-
-TestDetails::TestDetails(const TestDetails& details, int lineNumber_)
- : suiteName(details.suiteName)
- , testName(details.testName)
- , filename(details.filename)
- , lineNumber(lineNumber_)
-{
-}
-
-
-}
diff --git a/3rdparty/bx/3rdparty/UnitTest++/src/TestDetails.h b/3rdparty/bx/3rdparty/UnitTest++/src/TestDetails.h
deleted file mode 100644
index eae0e71e522..00000000000
--- a/3rdparty/bx/3rdparty/UnitTest++/src/TestDetails.h
+++ /dev/null
@@ -1,24 +0,0 @@
-#ifndef UNITTEST_TESTDETAILS_H
-#define UNITTEST_TESTDETAILS_H
-
-namespace UnitTest {
-
-class TestDetails
-{
-public:
- TestDetails(char const* testName, char const* suiteName, char const* filename, int lineNumber);
- TestDetails(const TestDetails& details, int lineNumber);
-
- char const* const suiteName;
- char const* const testName;
- char const* const filename;
- int const lineNumber;
-
- TestDetails(TestDetails const&); // Why is it public? --> http://gcc.gnu.org/bugs.html#cxx_rvalbind
-private:
- TestDetails& operator=(TestDetails const&);
-};
-
-}
-
-#endif
diff --git a/3rdparty/bx/3rdparty/UnitTest++/src/TestList.cpp b/3rdparty/bx/3rdparty/UnitTest++/src/TestList.cpp
deleted file mode 100644
index e31e6135b85..00000000000
--- a/3rdparty/bx/3rdparty/UnitTest++/src/TestList.cpp
+++ /dev/null
@@ -1,39 +0,0 @@
-#include "TestList.h"
-#include "Test.h"
-
-#include <cassert>
-
-namespace UnitTest {
-
-TestList::TestList()
- : m_head(0)
- , m_tail(0)
-{
-}
-
-void TestList::Add(Test* test)
-{
- if (m_tail == 0)
- {
- assert(m_head == 0);
- m_head = test;
- m_tail = test;
- }
- else
- {
- m_tail->next = test;
- m_tail = test;
- }
-}
-
-Test* TestList::GetHead() const
-{
- return m_head;
-}
-
-ListAdder::ListAdder(TestList& list, Test* test)
-{
- list.Add(test);
-}
-
-}
diff --git a/3rdparty/bx/3rdparty/UnitTest++/src/TestList.h b/3rdparty/bx/3rdparty/UnitTest++/src/TestList.h
deleted file mode 100644
index b17424b0312..00000000000
--- a/3rdparty/bx/3rdparty/UnitTest++/src/TestList.h
+++ /dev/null
@@ -1,32 +0,0 @@
-#ifndef UNITTEST_TESTLIST_H
-#define UNITTEST_TESTLIST_H
-
-
-namespace UnitTest {
-
-class Test;
-
-class TestList
-{
-public:
- TestList();
- void Add (Test* test);
-
- Test* GetHead() const;
-
-private:
- Test* m_head;
- Test* m_tail;
-};
-
-
-class ListAdder
-{
-public:
- ListAdder(TestList& list, Test* test);
-};
-
-}
-
-
-#endif
diff --git a/3rdparty/bx/3rdparty/UnitTest++/src/TestMacros.h b/3rdparty/bx/3rdparty/UnitTest++/src/TestMacros.h
deleted file mode 100644
index a297f15c3c0..00000000000
--- a/3rdparty/bx/3rdparty/UnitTest++/src/TestMacros.h
+++ /dev/null
@@ -1,113 +0,0 @@
-#ifndef UNITTEST_TESTMACROS_H
-#define UNITTEST_TESTMACROS_H
-
-#include "Config.h"
-#include "ExecuteTest.h"
-#include "AssertException.h"
-#include "TestDetails.h"
-#include "MemoryOutStream.h"
-
-#ifndef UNITTEST_POSIX
- #define UNITTEST_THROW_SIGNALS
-#else
- #include "Posix/SignalTranslator.h"
-#endif
-
-#ifdef TEST
- #error UnitTest++ redefines TEST
-#endif
-
-#ifdef TEST_EX
- #error UnitTest++ redefines TEST_EX
-#endif
-
-#ifdef TEST_FIXTURE_EX
- #error UnitTest++ redefines TEST_FIXTURE_EX
-#endif
-
-#define SUITE(Name) \
- namespace Suite##Name { \
- namespace UnitTestSuite { \
- inline char const* GetSuiteName () { \
- return #Name ; \
- } \
- } \
- } \
- namespace Suite##Name
-
-#define TEST_EX(Name, List) \
- class Test##Name : public UnitTest::Test \
- { \
- public: \
- Test##Name() : Test(#Name, UnitTestSuite::GetSuiteName(), __FILE__, __LINE__) {} \
- private: \
- virtual void RunImpl() const; \
- } test##Name##Instance; \
- \
- UnitTest::ListAdder adder##Name (List, &test##Name##Instance); \
- \
- void Test##Name::RunImpl() const
-
-
-#define TEST(Name) TEST_EX(Name, UnitTest::Test::GetTestList())
-
-
-#define TEST_FIXTURE_EX(Fixture, Name, List) \
- class Fixture##Name##Helper : public Fixture \
- { \
- public: \
- explicit Fixture##Name##Helper(UnitTest::TestDetails const& details) : m_details(details) {} \
- void RunImpl(); \
- UnitTest::TestDetails const& m_details; \
- private: \
- Fixture##Name##Helper(Fixture##Name##Helper const&); \
- Fixture##Name##Helper& operator =(Fixture##Name##Helper const&); \
- }; \
- \
- class Test##Fixture##Name : public UnitTest::Test \
- { \
- public: \
- Test##Fixture##Name() : Test(#Name, UnitTestSuite::GetSuiteName(), __FILE__, __LINE__) {} \
- private: \
- virtual void RunImpl() const; \
- } test##Fixture##Name##Instance; \
- \
- UnitTest::ListAdder adder##Fixture##Name (List, &test##Fixture##Name##Instance); \
- \
- void Test##Fixture##Name::RunImpl() const \
- { \
- bool ctorOk = false; \
- try { \
- Fixture##Name##Helper fixtureHelper(m_details); \
- ctorOk = true; \
- UnitTest::ExecuteTest(fixtureHelper, m_details); \
- } \
- catch (UnitTest::AssertException const& e) \
- { \
- UnitTest::CurrentTest::Results()->OnTestFailure(UnitTest::TestDetails(m_details.testName, m_details.suiteName, e.Filename(), e.LineNumber()), e.what()); \
- } \
- catch (std::exception const& e) \
- { \
- UnitTest::MemoryOutStream stream; \
- stream << "Unhandled exception: " << e.what(); \
- UnitTest::CurrentTest::Results()->OnTestFailure(m_details, stream.GetText()); \
- } \
- catch (...) { \
- if (ctorOk) \
- { \
- UnitTest::CurrentTest::Results()->OnTestFailure(UnitTest::TestDetails(m_details, __LINE__), \
- "Unhandled exception while destroying fixture " #Fixture); \
- } \
- else \
- { \
- UnitTest::CurrentTest::Results()->OnTestFailure(UnitTest::TestDetails(m_details, __LINE__), \
- "Unhandled exception while constructing fixture " #Fixture); \
- } \
- } \
- } \
- void Fixture##Name##Helper::RunImpl()
-
-#define TEST_FIXTURE(Fixture,Name) TEST_FIXTURE_EX(Fixture, Name, UnitTest::Test::GetTestList())
-
-
-#endif
diff --git a/3rdparty/bx/3rdparty/UnitTest++/src/TestReporter.cpp b/3rdparty/bx/3rdparty/UnitTest++/src/TestReporter.cpp
deleted file mode 100644
index 608d3c634b6..00000000000
--- a/3rdparty/bx/3rdparty/UnitTest++/src/TestReporter.cpp
+++ /dev/null
@@ -1,10 +0,0 @@
-#include "TestReporter.h"
-
-namespace UnitTest {
-
-
-TestReporter::~TestReporter()
-{
-}
-
-}
diff --git a/3rdparty/bx/3rdparty/UnitTest++/src/TestReporter.h b/3rdparty/bx/3rdparty/UnitTest++/src/TestReporter.h
deleted file mode 100644
index 5a2f404caaa..00000000000
--- a/3rdparty/bx/3rdparty/UnitTest++/src/TestReporter.h
+++ /dev/null
@@ -1,20 +0,0 @@
-#ifndef UNITTEST_TESTREPORTER_H
-#define UNITTEST_TESTREPORTER_H
-
-namespace UnitTest {
-
-class TestDetails;
-
-class TestReporter
-{
-public:
- virtual ~TestReporter();
-
- virtual void ReportTestStart(TestDetails const& test) = 0;
- virtual void ReportFailure(TestDetails const& test, char const* failure) = 0;
- virtual void ReportTestFinish(TestDetails const& test, float secondsElapsed) = 0;
- virtual void ReportSummary(int totalTestCount, int failedTestCount, int failureCount, float secondsElapsed) = 0;
-};
-
-}
-#endif
diff --git a/3rdparty/bx/3rdparty/UnitTest++/src/TestReporterStdout.cpp b/3rdparty/bx/3rdparty/UnitTest++/src/TestReporterStdout.cpp
deleted file mode 100644
index e63d3e2067c..00000000000
--- a/3rdparty/bx/3rdparty/UnitTest++/src/TestReporterStdout.cpp
+++ /dev/null
@@ -1,57 +0,0 @@
-#include "TestReporterStdout.h"
-#include <cstdio>
-
-#include "TestDetails.h"
-
-// cstdio doesn't pull in namespace std on VC6, so we do it here.
-#if defined(_MSC_VER) && (_MSC_VER == 1200)
- namespace std {}
-#endif
-
-#if defined(__ANDROID__)
-# include <android/log.h>
-# define outf(format, ...) __android_log_print(ANDROID_LOG_DEBUG, "", format, ##__VA_ARGS__)
-#else
-# define outf(format, ...) printf(format, ##__VA_ARGS__)
-#endif // defined(__ANDROID__)
-
-namespace UnitTest {
-
-void TestReporterStdout::ReportFailure(TestDetails const& details, char const* failure)
-{
-#if defined(__APPLE__) || defined(__GNUG__)
- char const* const errorFormat = "%s:%d: error: Failure in %s: %s\n";
-#else
- char const* const errorFormat = "%s(%d): error: Failure in %s: %s\n";
-#endif
-
- using namespace std;
- outf(errorFormat, details.filename, details.lineNumber, details.testName, failure);
-}
-
-void TestReporterStdout::ReportTestStart(TestDetails const& /*test*/)
-{
-}
-
-void TestReporterStdout::ReportTestFinish(TestDetails const& /*test*/, float)
-{
-}
-
-void TestReporterStdout::ReportSummary(int const totalTestCount, int const failedTestCount,
- int const failureCount, float secondsElapsed)
-{
- using namespace std;
-
- if (failureCount > 0)
- {
- outf("FAILURE: %d out of %d tests failed (%d failures).\n", failedTestCount, totalTestCount, failureCount);
- }
- else
- {
- outf("Success: %d tests passed.\n", totalTestCount);
- }
-
- outf("Test time: %.2f seconds.\n", secondsElapsed);
-}
-
-}
diff --git a/3rdparty/bx/3rdparty/UnitTest++/src/TestReporterStdout.h b/3rdparty/bx/3rdparty/UnitTest++/src/TestReporterStdout.h
deleted file mode 100644
index eacbba31d60..00000000000
--- a/3rdparty/bx/3rdparty/UnitTest++/src/TestReporterStdout.h
+++ /dev/null
@@ -1,19 +0,0 @@
-#ifndef UNITTEST_TESTREPORTERSTDOUT_H
-#define UNITTEST_TESTREPORTERSTDOUT_H
-
-#include "TestReporter.h"
-
-namespace UnitTest {
-
-class TestReporterStdout : public TestReporter
-{
-private:
- virtual void ReportTestStart(TestDetails const& test);
- virtual void ReportFailure(TestDetails const& test, char const* failure);
- virtual void ReportTestFinish(TestDetails const& test, float secondsElapsed);
- virtual void ReportSummary(int totalTestCount, int failedTestCount, int failureCount, float secondsElapsed);
-};
-
-}
-
-#endif
diff --git a/3rdparty/bx/3rdparty/UnitTest++/src/TestResults.cpp b/3rdparty/bx/3rdparty/UnitTest++/src/TestResults.cpp
deleted file mode 100644
index b3b67c0c8e2..00000000000
--- a/3rdparty/bx/3rdparty/UnitTest++/src/TestResults.cpp
+++ /dev/null
@@ -1,60 +0,0 @@
-#include "TestResults.h"
-#include "TestReporter.h"
-
-#include "TestDetails.h"
-
-namespace UnitTest {
-
-TestResults::TestResults(TestReporter* testReporter)
- : m_testReporter(testReporter)
- , m_totalTestCount(0)
- , m_failedTestCount(0)
- , m_failureCount(0)
- , m_currentTestFailed(false)
-{
-}
-
-void TestResults::OnTestStart(TestDetails const& test)
-{
- ++m_totalTestCount;
- m_currentTestFailed = false;
- if (m_testReporter)
- m_testReporter->ReportTestStart(test);
-}
-
-void TestResults::OnTestFailure(TestDetails const& test, char const* failure)
-{
- ++m_failureCount;
- if (!m_currentTestFailed)
- {
- ++m_failedTestCount;
- m_currentTestFailed = true;
- }
-
- if (m_testReporter)
- m_testReporter->ReportFailure(test, failure);
-}
-
-void TestResults::OnTestFinish(TestDetails const& test, float secondsElapsed)
-{
- if (m_testReporter)
- m_testReporter->ReportTestFinish(test, secondsElapsed);
-}
-
-int TestResults::GetTotalTestCount() const
-{
- return m_totalTestCount;
-}
-
-int TestResults::GetFailedTestCount() const
-{
- return m_failedTestCount;
-}
-
-int TestResults::GetFailureCount() const
-{
- return m_failureCount;
-}
-
-
-}
diff --git a/3rdparty/bx/3rdparty/UnitTest++/src/TestResults.h b/3rdparty/bx/3rdparty/UnitTest++/src/TestResults.h
deleted file mode 100644
index 8ef7fdad84e..00000000000
--- a/3rdparty/bx/3rdparty/UnitTest++/src/TestResults.h
+++ /dev/null
@@ -1,36 +0,0 @@
-#ifndef UNITTEST_TESTRESULTS_H
-#define UNITTEST_TESTRESULTS_H
-
-namespace UnitTest {
-
-class TestReporter;
-class TestDetails;
-
-class TestResults
-{
-public:
- explicit TestResults(TestReporter* reporter = 0);
-
- void OnTestStart(TestDetails const& test);
- void OnTestFailure(TestDetails const& test, char const* failure);
- void OnTestFinish(TestDetails const& test, float secondsElapsed);
-
- int GetTotalTestCount() const;
- int GetFailedTestCount() const;
- int GetFailureCount() const;
-
-private:
- TestReporter* m_testReporter;
- int m_totalTestCount;
- int m_failedTestCount;
- int m_failureCount;
-
- bool m_currentTestFailed;
-
- TestResults(TestResults const&);
- TestResults& operator =(TestResults const&);
-};
-
-}
-
-#endif
diff --git a/3rdparty/bx/3rdparty/UnitTest++/src/TestRunner.cpp b/3rdparty/bx/3rdparty/UnitTest++/src/TestRunner.cpp
deleted file mode 100644
index 5302554e897..00000000000
--- a/3rdparty/bx/3rdparty/UnitTest++/src/TestRunner.cpp
+++ /dev/null
@@ -1,76 +0,0 @@
-#include "TestRunner.h"
-#include "TestResults.h"
-#include "TestReporter.h"
-#include "TestReporterStdout.h"
-#include "TimeHelpers.h"
-#include "MemoryOutStream.h"
-
-#include <cstring>
-
-
-namespace UnitTest {
-
-int RunAllTests()
-{
- TestReporterStdout reporter;
- TestRunner runner(reporter);
- return runner.RunTestsIf(Test::GetTestList(), NULL, True(), 0);
-}
-
-
-TestRunner::TestRunner(TestReporter& reporter)
- : m_reporter(&reporter)
- , m_result(new TestResults(&reporter))
- , m_timer(new Timer)
-{
- m_timer->Start();
-}
-
-TestRunner::~TestRunner()
-{
- delete m_result;
- delete m_timer;
-}
-
-int TestRunner::Finish() const
-{
- float const secondsElapsed = static_cast<float>(m_timer->GetTimeInMs() / 1000.0);
- m_reporter->ReportSummary(m_result->GetTotalTestCount(),
- m_result->GetFailedTestCount(),
- m_result->GetFailureCount(),
- secondsElapsed);
-
- return m_result->GetFailureCount();
-}
-
-bool TestRunner::IsTestInSuite(const Test* const curTest, char const* suiteName) const
-{
- using namespace std;
- return (suiteName == NULL) || !strcmp(curTest->m_details.suiteName, suiteName);
-}
-
-void TestRunner::RunTest(TestResults* const result, Test* const curTest, int const maxTestTimeInMs) const
-{
- CurrentTest::Results() = result;
-
- Timer testTimer;
- testTimer.Start();
-
- result->OnTestStart(curTest->m_details);
-
- curTest->Run();
-
- double const testTimeInMs = testTimer.GetTimeInMs();
- if (maxTestTimeInMs > 0 && testTimeInMs > maxTestTimeInMs && !curTest->m_timeConstraintExempt)
- {
- MemoryOutStream stream;
- stream << "Global time constraint failed. Expected under " << maxTestTimeInMs <<
- "ms but took " << testTimeInMs << "ms.";
-
- result->OnTestFailure(curTest->m_details, stream.GetText());
- }
-
- result->OnTestFinish(curTest->m_details, static_cast<float>(testTimeInMs/1000.0));
-}
-
-}
diff --git a/3rdparty/bx/3rdparty/UnitTest++/src/TestRunner.h b/3rdparty/bx/3rdparty/UnitTest++/src/TestRunner.h
deleted file mode 100644
index 672355d928f..00000000000
--- a/3rdparty/bx/3rdparty/UnitTest++/src/TestRunner.h
+++ /dev/null
@@ -1,59 +0,0 @@
-#ifndef UNITTEST_TESTRUNNER_H
-#define UNITTEST_TESTRUNNER_H
-
-#include "Test.h"
-#include "TestList.h"
-#include "CurrentTest.h"
-
-namespace UnitTest {
-
-class TestReporter;
-class TestResults;
-class Timer;
-
-int RunAllTests();
-
-struct True
-{
- bool operator()(const Test* const) const
- {
- return true;
- }
-};
-
-class TestRunner
-{
-public:
- explicit TestRunner(TestReporter& reporter);
- ~TestRunner();
-
- template <class Predicate>
- int RunTestsIf(TestList const& list, char const* suiteName,
- const Predicate& predicate, int maxTestTimeInMs) const
- {
- Test* curTest = list.GetHead();
-
- while (curTest != 0)
- {
- if (IsTestInSuite(curTest, suiteName) && predicate(curTest))
- RunTest(m_result, curTest, maxTestTimeInMs);
-
- curTest = curTest->next;
- }
-
- return Finish();
- }
-
-private:
- TestReporter* m_reporter;
- TestResults* m_result;
- Timer* m_timer;
-
- int Finish() const;
- bool IsTestInSuite(const Test* const curTest, char const* suiteName) const;
- void RunTest(TestResults* const result, Test* const curTest, int const maxTestTimeInMs) const;
-};
-
-}
-
-#endif
diff --git a/3rdparty/bx/3rdparty/UnitTest++/src/TestSuite.h b/3rdparty/bx/3rdparty/UnitTest++/src/TestSuite.h
deleted file mode 100644
index 2812d8c9496..00000000000
--- a/3rdparty/bx/3rdparty/UnitTest++/src/TestSuite.h
+++ /dev/null
@@ -1,12 +0,0 @@
-#ifndef UNITTEST_TESTSUITE_H
-#define UNITTEST_TESTSUITE_H
-
-namespace UnitTestSuite
-{
- inline char const* GetSuiteName ()
- {
- return "DefaultSuite";
- }
-}
-
-#endif
diff --git a/3rdparty/bx/3rdparty/UnitTest++/src/TimeConstraint.cpp b/3rdparty/bx/3rdparty/UnitTest++/src/TimeConstraint.cpp
deleted file mode 100644
index f29bbccb849..00000000000
--- a/3rdparty/bx/3rdparty/UnitTest++/src/TimeConstraint.cpp
+++ /dev/null
@@ -1,29 +0,0 @@
-#include "TimeConstraint.h"
-#include "TestResults.h"
-#include "MemoryOutStream.h"
-#include "CurrentTest.h"
-
-namespace UnitTest {
-
-
-TimeConstraint::TimeConstraint(int ms, TestDetails const& details)
- : m_details(details)
- , m_maxMs(ms)
-{
- m_timer.Start();
-}
-
-TimeConstraint::~TimeConstraint()
-{
- double const totalTimeInMs = m_timer.GetTimeInMs();
- if (totalTimeInMs > m_maxMs)
- {
- MemoryOutStream stream;
- stream << "Time constraint failed. Expected to run test under " << m_maxMs <<
- "ms but took " << totalTimeInMs << "ms.";
-
- UnitTest::CurrentTest::Results()->OnTestFailure(m_details, stream.GetText());
- }
-}
-
-}
diff --git a/3rdparty/bx/3rdparty/UnitTest++/src/TimeConstraint.h b/3rdparty/bx/3rdparty/UnitTest++/src/TimeConstraint.h
deleted file mode 100644
index ac329145731..00000000000
--- a/3rdparty/bx/3rdparty/UnitTest++/src/TimeConstraint.h
+++ /dev/null
@@ -1,33 +0,0 @@
-#ifndef UNITTEST_TIMECONSTRAINT_H
-#define UNITTEST_TIMECONSTRAINT_H
-
-#include "TimeHelpers.h"
-
-namespace UnitTest {
-
-class TestResults;
-class TestDetails;
-
-class TimeConstraint
-{
-public:
- TimeConstraint(int ms, TestDetails const& details);
- ~TimeConstraint();
-
-private:
- void operator=(TimeConstraint const&);
- TimeConstraint(TimeConstraint const&);
-
- Timer m_timer;
- TestDetails const& m_details;
- int const m_maxMs;
-};
-
-#define UNITTEST_TIME_CONSTRAINT(ms) \
- UnitTest::TimeConstraint unitTest__timeConstraint__(ms, UnitTest::TestDetails(m_details, __LINE__))
-
-#define UNITTEST_TIME_CONSTRAINT_EXEMPT() do { m_timeConstraintExempt = true; } while (0)
-
-}
-
-#endif
diff --git a/3rdparty/bx/3rdparty/UnitTest++/src/TimeHelpers.h b/3rdparty/bx/3rdparty/UnitTest++/src/TimeHelpers.h
deleted file mode 100644
index f34ed008571..00000000000
--- a/3rdparty/bx/3rdparty/UnitTest++/src/TimeHelpers.h
+++ /dev/null
@@ -1,7 +0,0 @@
-#include "Config.h"
-
-#if defined UNITTEST_POSIX
- #include "Posix/TimeHelpers.h"
-#else
- #include "Win32/TimeHelpers.h"
-#endif
diff --git a/3rdparty/bx/3rdparty/UnitTest++/src/UnitTest++.h b/3rdparty/bx/3rdparty/UnitTest++/src/UnitTest++.h
deleted file mode 100644
index 3318735fd36..00000000000
--- a/3rdparty/bx/3rdparty/UnitTest++/src/UnitTest++.h
+++ /dev/null
@@ -1,18 +0,0 @@
-#ifndef UNITTESTCPP_H
-#define UNITTESTCPP_H
-
-//lint -esym(1509,*Fixture)
-
-#include "Config.h"
-#include "Test.h"
-#include "TestList.h"
-#include "TestSuite.h"
-#include "TestResults.h"
-
-#include "TestMacros.h"
-
-#include "CheckMacros.h"
-#include "TestRunner.h"
-#include "TimeConstraint.h"
-
-#endif
diff --git a/3rdparty/bx/3rdparty/UnitTest++/src/Win32/TimeHelpers.cpp b/3rdparty/bx/3rdparty/UnitTest++/src/Win32/TimeHelpers.cpp
deleted file mode 100644
index 69d0d88e764..00000000000
--- a/3rdparty/bx/3rdparty/UnitTest++/src/Win32/TimeHelpers.cpp
+++ /dev/null
@@ -1,47 +0,0 @@
-#include "TimeHelpers.h"
-#include <windows.h>
-
-namespace UnitTest {
-
-Timer::Timer()
- : m_threadHandle(::GetCurrentThread())
- , m_startTime(0)
-{
-#if defined(_MSC_VER) && (_MSC_VER == 1200) // VC6 doesn't have DWORD_PTR?
- typedef unsigned long DWORD_PTR;
-#endif
-
- DWORD_PTR systemMask;
- ::GetProcessAffinityMask(GetCurrentProcess(), &m_processAffinityMask, &systemMask);
- ::SetThreadAffinityMask(m_threadHandle, 1);
- ::QueryPerformanceFrequency(reinterpret_cast< LARGE_INTEGER* >(&m_frequency));
- ::SetThreadAffinityMask(m_threadHandle, m_processAffinityMask);
-}
-
-void Timer::Start()
-{
- m_startTime = GetTime();
-}
-
-double Timer::GetTimeInMs() const
-{
- __int64 const elapsedTime = GetTime() - m_startTime;
- double const seconds = double(elapsedTime) / double(m_frequency);
- return seconds * 1000.0;
-}
-
-__int64 Timer::GetTime() const
-{
- LARGE_INTEGER curTime;
- ::SetThreadAffinityMask(m_threadHandle, 1);
- ::QueryPerformanceCounter(&curTime);
- ::SetThreadAffinityMask(m_threadHandle, m_processAffinityMask);
- return curTime.QuadPart;
-}
-
-void TimeHelpers::SleepMs(int const ms)
-{
- ::Sleep(ms);
-}
-
-}
diff --git a/3rdparty/bx/3rdparty/UnitTest++/src/Win32/TimeHelpers.h b/3rdparty/bx/3rdparty/UnitTest++/src/Win32/TimeHelpers.h
deleted file mode 100644
index 088de247047..00000000000
--- a/3rdparty/bx/3rdparty/UnitTest++/src/Win32/TimeHelpers.h
+++ /dev/null
@@ -1,48 +0,0 @@
-#ifndef UNITTEST_TIMEHELPERS_H
-#define UNITTEST_TIMEHELPERS_H
-
-#include "../Config.h"
-
-
-#ifdef UNITTEST_MINGW
- #ifndef __int64
- #define __int64 long long
- #endif
-#endif
-
-namespace UnitTest {
-
-class Timer
-{
-public:
- Timer();
- void Start();
- double GetTimeInMs() const;
-
-private:
- __int64 GetTime() const;
-
- void* m_threadHandle;
-
-#if defined(_WIN64)
- unsigned __int64 m_processAffinityMask;
-#else
- unsigned long m_processAffinityMask;
-#endif
-
- __int64 m_startTime;
- __int64 m_frequency;
-};
-
-
-namespace TimeHelpers
-{
-void SleepMs (int ms);
-}
-
-
-}
-
-
-
-#endif
diff --git a/3rdparty/bx/3rdparty/UnitTest++/src/XmlTestReporter.cpp b/3rdparty/bx/3rdparty/UnitTest++/src/XmlTestReporter.cpp
deleted file mode 100644
index fe8966f8816..00000000000
--- a/3rdparty/bx/3rdparty/UnitTest++/src/XmlTestReporter.cpp
+++ /dev/null
@@ -1,127 +0,0 @@
-#include "XmlTestReporter.h"
-#include "Config.h"
-
-#include <iostream>
-#include <sstream>
-#include <string>
-
-using std::string;
-using std::ostringstream;
-using std::ostream;
-
-namespace {
-
-void ReplaceChar(string& str, char c, string const& replacement)
-{
- for (size_t pos = str.find(c); pos != string::npos; pos = str.find(c, pos + 1))
- str.replace(pos, 1, replacement);
-}
-
-string XmlEscape(string const& value)
-{
- string escaped = value;
-
- ReplaceChar(escaped, '&', "&amp;");
- ReplaceChar(escaped, '<', "&lt;");
- ReplaceChar(escaped, '>', "&gt;");
- ReplaceChar(escaped, '\'', "&apos;");
- ReplaceChar(escaped, '\"', "&quot;");
-
- return escaped;
-}
-
-string BuildFailureMessage(string const& file, int line, string const& message)
-{
- ostringstream failureMessage;
- failureMessage << file << "(" << line << ") : " << message;
- return failureMessage.str();
-}
-
-}
-
-namespace UnitTest {
-
-XmlTestReporter::XmlTestReporter(ostream& ostream)
- : m_ostream(ostream)
-{
-}
-
-void XmlTestReporter::ReportSummary(int totalTestCount, int failedTestCount,
- int failureCount, float secondsElapsed)
-{
- AddXmlElement(m_ostream, NULL);
-
- BeginResults(m_ostream, totalTestCount, failedTestCount, failureCount, secondsElapsed);
-
- DeferredTestResultList const& results = GetResults();
- for (DeferredTestResultList::const_iterator i = results.begin(); i != results.end(); ++i)
- {
- BeginTest(m_ostream, *i);
-
- if (i->failed)
- AddFailure(m_ostream, *i);
-
- EndTest(m_ostream, *i);
- }
-
- EndResults(m_ostream);
-}
-
-void XmlTestReporter::AddXmlElement(ostream& os, char const* encoding)
-{
- os << "<?xml version=\"1.0\"";
-
- if (encoding != NULL)
- os << " encoding=\"" << encoding << "\"";
-
- os << "?>";
-}
-
-void XmlTestReporter::BeginResults(std::ostream& os, int totalTestCount, int failedTestCount,
- int failureCount, float secondsElapsed)
-{
- os << "<unittest-results"
- << " tests=\"" << totalTestCount << "\""
- << " failedtests=\"" << failedTestCount << "\""
- << " failures=\"" << failureCount << "\""
- << " time=\"" << secondsElapsed << "\""
- << ">";
-}
-
-void XmlTestReporter::EndResults(std::ostream& os)
-{
- os << "</unittest-results>";
-}
-
-void XmlTestReporter::BeginTest(std::ostream& os, DeferredTestResult const& result)
-{
- os << "<test"
- << " suite=\"" << result.suiteName << "\""
- << " name=\"" << result.testName << "\""
- << " time=\"" << result.timeElapsed << "\"";
-}
-
-void XmlTestReporter::EndTest(std::ostream& os, DeferredTestResult const& result)
-{
- if (result.failed)
- os << "</test>";
- else
- os << "/>";
-}
-
-void XmlTestReporter::AddFailure(std::ostream& os, DeferredTestResult const& result)
-{
- os << ">"; // close <test> element
-
- for (DeferredTestResult::FailureVec::const_iterator it = result.failures.begin();
- it != result.failures.end();
- ++it)
- {
- string const escapedMessage = XmlEscape(it->second);
- string const message = BuildFailureMessage(result.failureFile, it->first, escapedMessage);
-
- os << "<failure" << " message=\"" << message << "\"" << "/>";
- }
-}
-
-}
diff --git a/3rdparty/bx/3rdparty/UnitTest++/src/XmlTestReporter.h b/3rdparty/bx/3rdparty/UnitTest++/src/XmlTestReporter.h
deleted file mode 100644
index 884123b18b6..00000000000
--- a/3rdparty/bx/3rdparty/UnitTest++/src/XmlTestReporter.h
+++ /dev/null
@@ -1,34 +0,0 @@
-#ifndef UNITTEST_XMLTESTREPORTER_H
-#define UNITTEST_XMLTESTREPORTER_H
-
-#include "DeferredTestReporter.h"
-
-#include <iosfwd>
-
-namespace UnitTest
-{
-
-class XmlTestReporter : public DeferredTestReporter
-{
-public:
- explicit XmlTestReporter(std::ostream& ostream);
-
- virtual void ReportSummary(int totalTestCount, int failedTestCount, int failureCount, float secondsElapsed);
-
-private:
- XmlTestReporter(XmlTestReporter const&);
- XmlTestReporter& operator=(XmlTestReporter const&);
-
- void AddXmlElement(std::ostream& os, char const* encoding);
- void BeginResults(std::ostream& os, int totalTestCount, int failedTestCount, int failureCount, float secondsElapsed);
- void EndResults(std::ostream& os);
- void BeginTest(std::ostream& os, DeferredTestResult const& result);
- void AddFailure(std::ostream& os, DeferredTestResult const& result);
- void EndTest(std::ostream& os, DeferredTestResult const& result);
-
- std::ostream& m_ostream;
-};
-
-}
-
-#endif
diff --git a/3rdparty/bx/3rdparty/UnitTest++/src/tests/Main.cpp b/3rdparty/bx/3rdparty/UnitTest++/src/tests/Main.cpp
deleted file mode 100644
index b2d9615808e..00000000000
--- a/3rdparty/bx/3rdparty/UnitTest++/src/tests/Main.cpp
+++ /dev/null
@@ -1,8 +0,0 @@
-#include "../UnitTest++.h"
-#include "../TestReporterStdout.h"
-
-
-int main(int, char const *[])
-{
- return UnitTest::RunAllTests();
-}
diff --git a/3rdparty/bx/3rdparty/UnitTest++/src/tests/RecordingReporter.h b/3rdparty/bx/3rdparty/UnitTest++/src/tests/RecordingReporter.h
deleted file mode 100644
index 982c294c448..00000000000
--- a/3rdparty/bx/3rdparty/UnitTest++/src/tests/RecordingReporter.h
+++ /dev/null
@@ -1,98 +0,0 @@
-#ifndef UNITTEST_RECORDINGREPORTER_H
-#define UNITTEST_RECORDINGREPORTER_H
-
-#include "../TestReporter.h"
-#include <cstring>
-
-#include "../TestDetails.h"
-
-struct RecordingReporter : public UnitTest::TestReporter
-{
-private:
- enum { kMaxStringLength = 256 };
-
-public:
- RecordingReporter()
- : testRunCount(0)
- , testFailedCount(0)
- , lastFailedLine(0)
- , testFinishedCount(0)
- , lastFinishedTestTime(0)
- , summaryTotalTestCount(0)
- , summaryFailedTestCount(0)
- , summaryFailureCount(0)
- , summarySecondsElapsed(0)
- {
- lastStartedSuite[0] = '\0';
- lastStartedTest[0] = '\0';
- lastFailedFile[0] = '\0';
- lastFailedSuite[0] = '\0';
- lastFailedTest[0] = '\0';
- lastFailedMessage[0] = '\0';
- lastFinishedSuite[0] = '\0';
- lastFinishedTest[0] = '\0';
- }
-
- virtual void ReportTestStart(UnitTest::TestDetails const& test)
- {
- using namespace std;
-
- ++testRunCount;
- strcpy(lastStartedSuite, test.suiteName);
- strcpy(lastStartedTest, test.testName);
- }
-
- virtual void ReportFailure(UnitTest::TestDetails const& test, char const* failure)
- {
- using namespace std;
-
- ++testFailedCount;
- strcpy(lastFailedFile, test.filename);
- lastFailedLine = test.lineNumber;
- strcpy(lastFailedSuite, test.suiteName);
- strcpy(lastFailedTest, test.testName);
- strcpy(lastFailedMessage, failure);
- }
-
- virtual void ReportTestFinish(UnitTest::TestDetails const& test, float testDuration)
- {
- using namespace std;
-
- ++testFinishedCount;
- strcpy(lastFinishedSuite, test.suiteName);
- strcpy(lastFinishedTest, test.testName);
- lastFinishedTestTime = testDuration;
- }
-
- virtual void ReportSummary(int totalTestCount, int failedTestCount, int failureCount, float secondsElapsed)
- {
- summaryTotalTestCount = totalTestCount;
- summaryFailedTestCount = failedTestCount;
- summaryFailureCount = failureCount;
- summarySecondsElapsed = secondsElapsed;
- }
-
- int testRunCount;
- char lastStartedSuite[kMaxStringLength];
- char lastStartedTest[kMaxStringLength];
-
- int testFailedCount;
- char lastFailedFile[kMaxStringLength];
- int lastFailedLine;
- char lastFailedSuite[kMaxStringLength];
- char lastFailedTest[kMaxStringLength];
- char lastFailedMessage[kMaxStringLength];
-
- int testFinishedCount;
- char lastFinishedSuite[kMaxStringLength];
- char lastFinishedTest[kMaxStringLength];
- float lastFinishedTestTime;
-
- int summaryTotalTestCount;
- int summaryFailedTestCount;
- int summaryFailureCount;
- float summarySecondsElapsed;
-};
-
-
-#endif
diff --git a/3rdparty/bx/3rdparty/UnitTest++/src/tests/ScopedCurrentTest.h b/3rdparty/bx/3rdparty/UnitTest++/src/tests/ScopedCurrentTest.h
deleted file mode 100644
index e03ae0a00db..00000000000
--- a/3rdparty/bx/3rdparty/UnitTest++/src/tests/ScopedCurrentTest.h
+++ /dev/null
@@ -1,37 +0,0 @@
-#ifndef UNITTEST_SCOPEDCURRENTTEST_H
-#define UNITTEST_SCOPEDCURRENTTEST_H
-
-#include "../CurrentTest.h"
-#include <cstddef>
-
-class ScopedCurrentTest
-{
-public:
- ScopedCurrentTest()
- : m_oldTestResults(UnitTest::CurrentTest::Results())
- , m_oldTestDetails(UnitTest::CurrentTest::Details())
- {
- }
-
- explicit ScopedCurrentTest(UnitTest::TestResults& newResults, const UnitTest::TestDetails* newDetails = NULL)
- : m_oldTestResults(UnitTest::CurrentTest::Results())
- , m_oldTestDetails(UnitTest::CurrentTest::Details())
- {
- UnitTest::CurrentTest::Results() = &newResults;
-
- if (newDetails != NULL)
- UnitTest::CurrentTest::Details() = newDetails;
- }
-
- ~ScopedCurrentTest()
- {
- UnitTest::CurrentTest::Results() = m_oldTestResults;
- UnitTest::CurrentTest::Details() = m_oldTestDetails;
- }
-
-private:
- UnitTest::TestResults* m_oldTestResults;
- const UnitTest::TestDetails* m_oldTestDetails;
-};
-
-#endif
diff --git a/3rdparty/bx/3rdparty/UnitTest++/src/tests/TestAssertHandler.cpp b/3rdparty/bx/3rdparty/UnitTest++/src/tests/TestAssertHandler.cpp
deleted file mode 100644
index a5fd07cead2..00000000000
--- a/3rdparty/bx/3rdparty/UnitTest++/src/tests/TestAssertHandler.cpp
+++ /dev/null
@@ -1,44 +0,0 @@
-#include "../UnitTest++.h"
-#include "../AssertException.h"
-#include "../ReportAssert.h"
-
-using namespace UnitTest;
-
-namespace {
-
-TEST(ReportAssertThrowsAssertException)
-{
- bool caught = false;
-
- try
- {
- ReportAssert("", "", 0);
- }
- catch(AssertException const&)
- {
- caught = true;
- }
-
- CHECK (true == caught);
-}
-
-TEST(ReportAssertSetsCorrectInfoInException)
-{
- const int lineNumber = 12345;
- const char* description = "description";
- const char* filename = "filename";
-
- try
- {
- ReportAssert(description, filename, lineNumber);
- }
- catch(AssertException const& e)
- {
- CHECK_EQUAL(description, e.what());
- CHECK_EQUAL(filename, e.Filename());
- CHECK_EQUAL(lineNumber, e.LineNumber());
- }
-}
-
-
-}
diff --git a/3rdparty/bx/3rdparty/UnitTest++/src/tests/TestCheckMacros.cpp b/3rdparty/bx/3rdparty/UnitTest++/src/tests/TestCheckMacros.cpp
deleted file mode 100644
index 37d184b2fdb..00000000000
--- a/3rdparty/bx/3rdparty/UnitTest++/src/tests/TestCheckMacros.cpp
+++ /dev/null
@@ -1,801 +0,0 @@
-#include "../UnitTest++.h"
-#include "../CurrentTest.h"
-#include "RecordingReporter.h"
-#include "ScopedCurrentTest.h"
-
-using namespace std;
-
-namespace {
-
-TEST(CheckSucceedsOnTrue)
-{
- bool failure = true;
- {
- RecordingReporter reporter;
- UnitTest::TestResults testResults(&reporter);
-
- ScopedCurrentTest scopedResults(testResults);
- CHECK(true);
-
- failure = (testResults.GetFailureCount() > 0);
- }
-
- CHECK(!failure);
-}
-
-TEST(CheckFailsOnFalse)
-{
- bool failure = false;
- {
- RecordingReporter reporter;
- UnitTest::TestResults testResults(&reporter);
- ScopedCurrentTest scopedResults(testResults);
- CHECK(false);
- failure = (testResults.GetFailureCount() > 0);
- }
-
- CHECK(failure);
-}
-
-TEST(FailureReportsCorrectTestName)
-{
- RecordingReporter reporter;
- {
- UnitTest::TestResults testResults(&reporter);
- ScopedCurrentTest scopedResults(testResults);
- CHECK(false);
- }
-
- CHECK_EQUAL(m_details.testName, reporter.lastFailedTest);
-}
-
-TEST(CheckFailureIncludesCheckContents)
-{
- RecordingReporter reporter;
- {
- UnitTest::TestResults testResults(&reporter);
- ScopedCurrentTest scopedResults(testResults);
- const bool yaddayadda = false;
- CHECK(yaddayadda);
- }
-
- CHECK(strstr(reporter.lastFailedMessage, "yaddayadda"));
-}
-
-int ThrowingFunction()
-{
- throw "Doh";
-}
-
-TEST(CheckFailsOnException)
-{
- bool failure = false;
- {
- RecordingReporter reporter;
- UnitTest::TestResults testResults(&reporter);
- ScopedCurrentTest scopedResults(testResults);
- CHECK(ThrowingFunction() == 1);
- failure = (testResults.GetFailureCount() > 0);
- }
-
- CHECK(failure);
-}
-
-TEST(CheckFailureBecauseOfExceptionIncludesCheckContents)
-{
- RecordingReporter reporter;
- {
- UnitTest::TestResults testResults(&reporter);
- ScopedCurrentTest scopedResults(testResults);
- CHECK(ThrowingFunction() == 1);
- }
-
- CHECK(strstr(reporter.lastFailedMessage, "ThrowingFunction() == 1"));
-}
-
-TEST(CheckEqualSucceedsOnEqual)
-{
- bool failure = true;
- {
- RecordingReporter reporter;
- UnitTest::TestResults testResults(&reporter);
- ScopedCurrentTest scopedResults(testResults);
- CHECK_EQUAL(1, 1);
- failure = (testResults.GetFailureCount() > 0);
- }
-
- CHECK(!failure);
-}
-
-TEST(CheckEqualFailsOnNotEqual)
-{
- bool failure = false;
- {
- RecordingReporter reporter;
- UnitTest::TestResults testResults(&reporter);
- ScopedCurrentTest scopedResults(testResults);
- CHECK_EQUAL(1, 2);
- failure = (testResults.GetFailureCount() > 0);
- }
-
- CHECK(failure);
-}
-
-TEST(CheckEqualFailsOnException)
-{
- bool failure = false;
- {
- RecordingReporter reporter;
- UnitTest::TestResults testResults(&reporter);
- ScopedCurrentTest scopedResults(testResults);
- CHECK_EQUAL(ThrowingFunction(), 1);
- failure = (testResults.GetFailureCount() > 0);
- }
-
- CHECK(failure);
-}
-
-TEST(CheckEqualFailureContainsCorrectDetails)
-{
- int line = 0;
- RecordingReporter reporter;
- {
- UnitTest::TestResults testResults(&reporter);
- UnitTest::TestDetails const testDetails("testName", "suiteName", "filename", -1);
- ScopedCurrentTest scopedResults(testResults, &testDetails);
-
- CHECK_EQUAL(1, 123); line = __LINE__;
- }
-
- CHECK_EQUAL("testName", reporter.lastFailedTest);
- CHECK_EQUAL("suiteName", reporter.lastFailedSuite);
- CHECK_EQUAL("filename", reporter.lastFailedFile);
- CHECK_EQUAL(line, reporter.lastFailedLine);
-}
-
-TEST(CheckEqualFailureBecauseOfExceptionContainsCorrectDetails)
-{
- int line = 0;
- RecordingReporter reporter;
- {
- UnitTest::TestResults testResults(&reporter);
- UnitTest::TestDetails const testDetails("testName", "suiteName", "filename", -1);
- ScopedCurrentTest scopedResults(testResults, &testDetails);
-
- CHECK_EQUAL(ThrowingFunction(), 123); line = __LINE__;
- }
-
- CHECK_EQUAL("testName", reporter.lastFailedTest);
- CHECK_EQUAL("suiteName", reporter.lastFailedSuite);
- CHECK_EQUAL("filename", reporter.lastFailedFile);
- CHECK_EQUAL(line, reporter.lastFailedLine);
-}
-
-TEST(CheckEqualFailureBecauseOfExceptionIncludesCheckContents)
-{
- RecordingReporter reporter;
- {
- UnitTest::TestResults testResults(&reporter);
- ScopedCurrentTest scopedResults(testResults);
- CHECK_EQUAL(ThrowingFunction(), 123);
- }
-
- CHECK(strstr(reporter.lastFailedMessage, "ThrowingFunction()"));
- CHECK(strstr(reporter.lastFailedMessage, "123"));
-}
-
-int g_sideEffect = 0;
-int FunctionWithSideEffects()
-{
- ++g_sideEffect;
- return 1;
-}
-
-TEST(CheckEqualDoesNotHaveSideEffectsWhenPassing)
-{
- g_sideEffect = 0;
- {
- UnitTest::TestResults testResults;
- ScopedCurrentTest scopedResults(testResults);
- CHECK_EQUAL(1, FunctionWithSideEffects());
- }
- CHECK_EQUAL(1, g_sideEffect);
-}
-
-TEST(CheckEqualDoesNotHaveSideEffectsWhenFailing)
-{
- g_sideEffect = 0;
- {
- UnitTest::TestResults testResults;
- ScopedCurrentTest scopedResults(testResults);
- CHECK_EQUAL(2, FunctionWithSideEffects());
- }
- CHECK_EQUAL(1, g_sideEffect);
-}
-
-
-TEST(CheckCloseSucceedsOnEqual)
-{
- bool failure = true;
- {
- RecordingReporter reporter;
- UnitTest::TestResults testResults(&reporter);
- ScopedCurrentTest scopedResults(testResults);
- CHECK_CLOSE (1.0f, 1.001f, 0.01f);
- failure = (testResults.GetFailureCount() > 0);
- }
-
- CHECK(!failure);
-}
-
-TEST(CheckCloseFailsOnNotEqual)
-{
- bool failure = false;
- {
- RecordingReporter reporter;
- UnitTest::TestResults testResults(&reporter);
- ScopedCurrentTest scopedResults(testResults);
- CHECK_CLOSE (1.0f, 1.1f, 0.01f);
- failure = (testResults.GetFailureCount() > 0);
- }
-
- CHECK(failure);
-}
-
-TEST(CheckCloseFailsOnException)
-{
- bool failure = false;
- {
- RecordingReporter reporter;
- UnitTest::TestResults testResults(&reporter);
- ScopedCurrentTest scopedResults(testResults);
- CHECK_CLOSE ((float)ThrowingFunction(), 1.0001f, 0.1f);
- failure = (testResults.GetFailureCount() > 0);
- }
-
- CHECK(failure);
-}
-
-TEST(CheckCloseFailureContainsCorrectDetails)
-{
- int line = 0;
- RecordingReporter reporter;
- {
- UnitTest::TestResults testResults(&reporter);
- UnitTest::TestDetails testDetails("test", "suite", "filename", -1);
- ScopedCurrentTest scopedResults(testResults, &testDetails);
-
- CHECK_CLOSE (1.0f, 1.1f, 0.01f); line = __LINE__;
- }
-
- CHECK_EQUAL("test", reporter.lastFailedTest);
- CHECK_EQUAL("suite", reporter.lastFailedSuite);
- CHECK_EQUAL("filename", reporter.lastFailedFile);
- CHECK_EQUAL(line, reporter.lastFailedLine);
-}
-
-TEST(CheckCloseFailureBecauseOfExceptionContainsCorrectDetails)
-{
- int line = 0;
- RecordingReporter reporter;
- {
- UnitTest::TestResults testResults(&reporter);
- UnitTest::TestDetails testDetails("closeTest", "closeSuite", "filename", -1);
- ScopedCurrentTest scopedResults(testResults, &testDetails);
- CHECK_CLOSE ((float)ThrowingFunction(), 1.0001f, 0.1f); line = __LINE__;
- }
-
- CHECK_EQUAL("closeTest", reporter.lastFailedTest);
- CHECK_EQUAL("closeSuite", reporter.lastFailedSuite);
- CHECK_EQUAL("filename", reporter.lastFailedFile);
- CHECK_EQUAL(line, reporter.lastFailedLine);
-}
-
-TEST(CheckCloseFailureBecauseOfExceptionIncludesCheckContents)
-{
- RecordingReporter reporter;
- {
- UnitTest::TestResults testResults(&reporter);
- ScopedCurrentTest scopedResults(testResults);
- CHECK_CLOSE ((float)ThrowingFunction(), 1.0001f, 0.1f);
- }
-
- CHECK(strstr(reporter.lastFailedMessage, "(float)ThrowingFunction()"));
- CHECK(strstr(reporter.lastFailedMessage, "1.0001f"));
-}
-
-TEST(CheckCloseDoesNotHaveSideEffectsWhenPassing)
-{
- g_sideEffect = 0;
- {
- UnitTest::TestResults testResults;
- ScopedCurrentTest scopedResults(testResults);
- CHECK_CLOSE (1, FunctionWithSideEffects(), 0.1f);
- }
- CHECK_EQUAL(1, g_sideEffect);
-}
-
-TEST(CheckCloseDoesNotHaveSideEffectsWhenFailing)
-{
- g_sideEffect = 0;
- {
- UnitTest::TestResults testResults;
- ScopedCurrentTest scopedResults(testResults);
- CHECK_CLOSE (2, FunctionWithSideEffects(), 0.1f);
- }
- CHECK_EQUAL(1, g_sideEffect);
-}
-
-
-class ThrowingObject
-{
-public:
- float operator[](int) const
- {
- throw "Test throw";
- }
-};
-
-
-TEST(CheckArrayCloseSucceedsOnEqual)
-{
- bool failure = true;
- {
- RecordingReporter reporter;
- UnitTest::TestResults testResults(&reporter);
- ScopedCurrentTest scopedResults(testResults);
- const float data[4] = { 0, 1, 2, 3 };
- CHECK_ARRAY_CLOSE (data, data, 4, 0.01f);
- failure = (testResults.GetFailureCount() > 0);
- }
-
- CHECK(!failure);
-}
-
-TEST(CheckArrayCloseFailsOnNotEqual)
-{
- bool failure = false;
- {
- RecordingReporter reporter;
- UnitTest::TestResults testResults(&reporter);
- ScopedCurrentTest scopedResults(testResults);
-
- int const data1[4] = { 0, 1, 2, 3 };
- int const data2[4] = { 0, 1, 3, 3 };
- CHECK_ARRAY_CLOSE (data1, data2, 4, 0.01f);
-
- failure = (testResults.GetFailureCount() > 0);
- }
-
- CHECK(failure);
-}
-
-TEST(CheckArrayCloseFailureIncludesCheckExpectedAndActual)
-{
- RecordingReporter reporter;
- {
- UnitTest::TestResults testResults(&reporter);
- ScopedCurrentTest scopedResults(testResults);
-
- int const data1[4] = { 0, 1, 2, 3 };
- int const data2[4] = { 0, 1, 3, 3 };
- CHECK_ARRAY_CLOSE (data1, data2, 4, 0.01f);
- }
-
- CHECK(strstr(reporter.lastFailedMessage, "xpected [ 0 1 2 3 ]"));
- CHECK(strstr(reporter.lastFailedMessage, "was [ 0 1 3 3 ]"));
-}
-
-TEST(CheckArrayCloseFailureContainsCorrectDetails)
-{
- int line = 0;
- RecordingReporter reporter;
- {
- UnitTest::TestResults testResults(&reporter);
- UnitTest::TestDetails testDetails("arrayCloseTest", "arrayCloseSuite", "filename", -1);
- ScopedCurrentTest scopedResults(testResults, &testDetails);
-
- int const data1[4] = { 0, 1, 2, 3 };
- int const data2[4] = { 0, 1, 3, 3 };
- CHECK_ARRAY_CLOSE (data1, data2, 4, 0.01f); line = __LINE__;
- }
-
- CHECK_EQUAL("arrayCloseTest", reporter.lastFailedTest);
- CHECK_EQUAL("arrayCloseSuite", reporter.lastFailedSuite);
- CHECK_EQUAL("filename", reporter.lastFailedFile);
- CHECK_EQUAL(line, reporter.lastFailedLine);
-}
-
-TEST(CheckArrayCloseFailureBecauseOfExceptionContainsCorrectDetails)
-{
- int line = 0;
- RecordingReporter reporter;
- {
- UnitTest::TestResults testResults(&reporter);
- UnitTest::TestDetails testDetails("arrayCloseTest", "arrayCloseSuite", "filename", -1);
- ScopedCurrentTest scopedResults(testResults, &testDetails);
-
- int const data[4] = { 0, 1, 2, 3 };
- CHECK_ARRAY_CLOSE (data, ThrowingObject(), 4, 0.01f); line = __LINE__;
- }
-
- CHECK_EQUAL("arrayCloseTest", reporter.lastFailedTest);
- CHECK_EQUAL("arrayCloseSuite", reporter.lastFailedSuite);
- CHECK_EQUAL("filename", reporter.lastFailedFile);
- CHECK_EQUAL(line, reporter.lastFailedLine);
-}
-
-TEST(CheckArrayCloseFailureIncludesTolerance)
-{
- RecordingReporter reporter;
- {
- UnitTest::TestResults testResults(&reporter);
- ScopedCurrentTest scopedResults(testResults);
-
- float const data1[4] = { 0, 1, 2, 3 };
- float const data2[4] = { 0, 1, 3, 3 };
- CHECK_ARRAY_CLOSE (data1, data2, 4, 0.01f);
- }
-
- CHECK(strstr(reporter.lastFailedMessage, "0.01"));
-}
-
-
-TEST(CheckArrayCloseFailsOnException)
-{
- bool failure = false;
- {
- RecordingReporter reporter;
- UnitTest::TestResults testResults(&reporter);
- ScopedCurrentTest scopedResults(testResults);
-
- const float data[4] = { 0, 1, 2, 3 };
- ThrowingObject obj;
- CHECK_ARRAY_CLOSE (data, obj, 3, 0.01f);
-
- failure = (testResults.GetFailureCount() > 0);
- }
-
- CHECK(failure);
-}
-
-TEST(CheckArrayCloseFailureOnExceptionIncludesCheckContents)
-{
- RecordingReporter reporter;
- {
- UnitTest::TestResults testResults(&reporter);
- ScopedCurrentTest scopedResults(testResults);
-
- const float data[4] = { 0, 1, 2, 3 };
- ThrowingObject obj;
- CHECK_ARRAY_CLOSE (data, obj, 3, 0.01f);
- }
-
- CHECK(strstr(reporter.lastFailedMessage, "data"));
- CHECK(strstr(reporter.lastFailedMessage, "obj"));
-}
-
-
-TEST(CheckArrayEqualSuceedsOnEqual)
-{
- bool failure = true;
- {
- RecordingReporter reporter;
- UnitTest::TestResults testResults(&reporter);
- ScopedCurrentTest scopedResults(testResults);
-
- const float data[4] = { 0, 1, 2, 3 };
- CHECK_ARRAY_EQUAL (data, data, 4);
-
- failure = (testResults.GetFailureCount() > 0);
- }
-
- CHECK(!failure);
-}
-
-TEST(CheckArrayEqualFailsOnNotEqual)
-{
- bool failure = false;
- {
- RecordingReporter reporter;
- UnitTest::TestResults testResults(&reporter);
- ScopedCurrentTest scopedResults(testResults);
-
- int const data1[4] = { 0, 1, 2, 3 };
- int const data2[4] = { 0, 1, 3, 3 };
- CHECK_ARRAY_EQUAL (data1, data2, 4);
-
- failure = (testResults.GetFailureCount() > 0);
- }
-
- CHECK(failure);
-}
-
-TEST(CheckArrayEqualFailureIncludesCheckExpectedAndActual)
-{
- RecordingReporter reporter;
- {
- UnitTest::TestResults testResults(&reporter);
- ScopedCurrentTest scopedResults(testResults);
-
- int const data1[4] = { 0, 1, 2, 3 };
- int const data2[4] = { 0, 1, 3, 3 };
- CHECK_ARRAY_EQUAL (data1, data2, 4);
- }
-
- CHECK(strstr(reporter.lastFailedMessage, "xpected [ 0 1 2 3 ]"));
- CHECK(strstr(reporter.lastFailedMessage, "was [ 0 1 3 3 ]"));
-}
-
-TEST(CheckArrayEqualFailureContainsCorrectInfo)
-{
- int line = 0;
- RecordingReporter reporter;
- {
- UnitTest::TestResults testResults(&reporter);
- ScopedCurrentTest scopedResults(testResults);
-
- int const data1[4] = { 0, 1, 2, 3 };
- int const data2[4] = { 0, 1, 3, 3 };
- CHECK_ARRAY_EQUAL (data1, data2, 4); line = __LINE__;
- }
-
- CHECK_EQUAL("CheckArrayEqualFailureContainsCorrectInfo", reporter.lastFailedTest);
- CHECK_EQUAL(__FILE__, reporter.lastFailedFile);
- CHECK_EQUAL(line, reporter.lastFailedLine);
-}
-
-TEST(CheckArrayEqualFailsOnException)
-{
- bool failure = false;
- {
- RecordingReporter reporter;
- UnitTest::TestResults testResults(&reporter);
- ScopedCurrentTest scopedResults(testResults);
-
- const float data[4] = { 0, 1, 2, 3 };
- ThrowingObject obj;
- CHECK_ARRAY_EQUAL (data, obj, 3);
-
- failure = (testResults.GetFailureCount() > 0);
- }
-
- CHECK(failure);
-}
-
-TEST(CheckArrayEqualFailureOnExceptionIncludesCheckContents)
-{
- RecordingReporter reporter;
- {
- UnitTest::TestResults testResults(&reporter);
- ScopedCurrentTest scopedResults(testResults);
-
- const float data[4] = { 0, 1, 2, 3 };
- ThrowingObject obj;
- CHECK_ARRAY_EQUAL (data, obj, 3);
- }
-
- CHECK(strstr(reporter.lastFailedMessage, "data"));
- CHECK(strstr(reporter.lastFailedMessage, "obj"));
-}
-
-float const* FunctionWithSideEffects2()
-{
- ++g_sideEffect;
- static float const data[] = {1,2,3,4};
- return data;
-}
-
-TEST(CheckArrayCloseDoesNotHaveSideEffectsWhenPassing)
-{
- g_sideEffect = 0;
- {
- UnitTest::TestResults testResults;
- ScopedCurrentTest scopedResults(testResults);
-
- const float data[] = { 0, 1, 2, 3 };
- CHECK_ARRAY_CLOSE (data, FunctionWithSideEffects2(), 4, 0.01f);
- }
- CHECK_EQUAL(1, g_sideEffect);
-}
-
-TEST(CheckArrayCloseDoesNotHaveSideEffectsWhenFailing)
-{
- g_sideEffect = 0;
- {
- UnitTest::TestResults testResults;
- ScopedCurrentTest scopedResults(testResults);
-
- const float data[] = { 0, 1, 3, 3 };
- CHECK_ARRAY_CLOSE (data, FunctionWithSideEffects2(), 4, 0.01f);
- }
-
- CHECK_EQUAL(1, g_sideEffect);
-}
-
-class ThrowingObject2D
-{
-public:
- float* operator[](int) const
- {
- throw "Test throw";
- }
-};
-
-
-TEST(CheckArray2DCloseSucceedsOnEqual)
-{
- bool failure = true;
- {
- RecordingReporter reporter;
- UnitTest::TestResults testResults(&reporter);
- ScopedCurrentTest scopedResults(testResults);
-
- const float data[2][2] = { {0, 1}, {2, 3} };
- CHECK_ARRAY2D_CLOSE (data, data, 2, 2, 0.01f);
-
- failure = (testResults.GetFailureCount() > 0);
- }
-
- CHECK(!failure);
-}
-
-TEST(CheckArray2DCloseFailsOnNotEqual)
-{
- bool failure = false;
- {
- RecordingReporter reporter;
- UnitTest::TestResults testResults(&reporter);
- ScopedCurrentTest scopedResults(testResults);
-
- int const data1[2][2] = { {0, 1}, {2, 3} };
- int const data2[2][2] = { {0, 1}, {3, 3} };
- CHECK_ARRAY2D_CLOSE (data1, data2, 2, 2, 0.01f);
-
- failure = (testResults.GetFailureCount() > 0);
- }
-
- CHECK(failure);
-}
-
-TEST(CheckArray2DCloseFailureIncludesCheckExpectedAndActual)
-{
- RecordingReporter reporter;
- {
- UnitTest::TestResults testResults(&reporter);
- ScopedCurrentTest scopedResults(testResults);
-
- int const data1[2][2] = { {0, 1}, {2, 3} };
- int const data2[2][2] = { {0, 1}, {3, 3} };
-
- CHECK_ARRAY2D_CLOSE (data1, data2, 2, 2, 0.01f);
- }
-
- CHECK(strstr(reporter.lastFailedMessage, "xpected [ [ 0 1 ] [ 2 3 ] ]"));
- CHECK(strstr(reporter.lastFailedMessage, "was [ [ 0 1 ] [ 3 3 ] ]"));
-}
-
-TEST(CheckArray2DCloseFailureContainsCorrectDetails)
-{
- int line = 0;
- RecordingReporter reporter;
- {
- UnitTest::TestResults testResults(&reporter);
- UnitTest::TestDetails testDetails("array2DCloseTest", "array2DCloseSuite", "filename", -1);
- ScopedCurrentTest scopedResults(testResults, &testDetails);
-
- int const data1[2][2] = { {0, 1}, {2, 3} };
- int const data2[2][2] = { {0, 1}, {3, 3} };
- CHECK_ARRAY2D_CLOSE (data1, data2, 2, 2, 0.01f); line = __LINE__;
- }
-
- CHECK_EQUAL("array2DCloseTest", reporter.lastFailedTest);
- CHECK_EQUAL("array2DCloseSuite", reporter.lastFailedSuite);
- CHECK_EQUAL("filename", reporter.lastFailedFile);
- CHECK_EQUAL(line, reporter.lastFailedLine);
-}
-
-TEST(CheckArray2DCloseFailureBecauseOfExceptionContainsCorrectDetails)
-{
- int line = 0;
- RecordingReporter reporter;
- {
- UnitTest::TestResults testResults(&reporter);
- UnitTest::TestDetails testDetails("array2DCloseTest", "array2DCloseSuite", "filename", -1);
- ScopedCurrentTest scopedResults(testResults, &testDetails);
-
- const float data[2][2] = { {0, 1}, {2, 3} };
- CHECK_ARRAY2D_CLOSE (data, ThrowingObject2D(), 2, 2, 0.01f); line = __LINE__;
- }
-
- CHECK_EQUAL("array2DCloseTest", reporter.lastFailedTest);
- CHECK_EQUAL("array2DCloseSuite", reporter.lastFailedSuite);
- CHECK_EQUAL("filename", reporter.lastFailedFile);
- CHECK_EQUAL(line, reporter.lastFailedLine);
-}
-
-TEST(CheckArray2DCloseFailureIncludesTolerance)
-{
- RecordingReporter reporter;
- {
- UnitTest::TestResults testResults(&reporter);
- ScopedCurrentTest scopedResults(testResults);
-
- float const data1[2][2] = { {0, 1}, {2, 3} };
- float const data2[2][2] = { {0, 1}, {3, 3} };
- CHECK_ARRAY2D_CLOSE (data1, data2, 2, 2, 0.01f);
- }
-
- CHECK(strstr(reporter.lastFailedMessage, "0.01"));
-}
-
-TEST(CheckArray2DCloseFailsOnException)
-{
- bool failure = false;
- {
- RecordingReporter reporter;
- UnitTest::TestResults testResults(&reporter);
- ScopedCurrentTest scopedResults(testResults);
-
- const float data[2][2] = { {0, 1}, {2, 3} };
- ThrowingObject2D obj;
- CHECK_ARRAY2D_CLOSE (data, obj, 2, 2, 0.01f);
-
- failure = (testResults.GetFailureCount() > 0);
- }
-
- CHECK(failure);
-}
-
-TEST(CheckArray2DCloseFailureOnExceptionIncludesCheckContents)
-{
- RecordingReporter reporter;
- {
- UnitTest::TestResults testResults(&reporter);
- ScopedCurrentTest scopedResults(testResults);
-
- const float data[2][2] = { {0, 1}, {2, 3} };
- ThrowingObject2D obj;
- CHECK_ARRAY2D_CLOSE (data, obj, 2, 2, 0.01f);
- }
-
- CHECK(strstr(reporter.lastFailedMessage, "data"));
- CHECK(strstr(reporter.lastFailedMessage, "obj"));
-}
-
-float const* const* FunctionWithSideEffects3()
-{
- ++g_sideEffect;
- static float const data1[] = {0,1};
- static float const data2[] = {2,3};
- static const float* const data[] = {data1, data2};
- return data;
-}
-
-TEST(CheckArray2DCloseDoesNotHaveSideEffectsWhenPassing)
-{
- g_sideEffect = 0;
- {
- UnitTest::TestResults testResults;
- ScopedCurrentTest scopedResults(testResults);
-
- const float data[2][2] = { {0, 1}, {2, 3} };
- CHECK_ARRAY2D_CLOSE (data, FunctionWithSideEffects3(), 2, 2, 0.01f);
- }
- CHECK_EQUAL(1, g_sideEffect);
-}
-
-TEST(CheckArray2DCloseDoesNotHaveSideEffectsWhenFailing)
-{
- g_sideEffect = 0;
- {
- UnitTest::TestResults testResults;
- ScopedCurrentTest scopedResults(testResults);
-
- const float data[2][2] = { {0, 1}, {3, 3} };
- CHECK_ARRAY2D_CLOSE (data, FunctionWithSideEffects3(), 2, 2, 0.01f);
- }
- CHECK_EQUAL(1, g_sideEffect);
-}
-
-}
diff --git a/3rdparty/bx/3rdparty/UnitTest++/src/tests/TestChecks.cpp b/3rdparty/bx/3rdparty/UnitTest++/src/tests/TestChecks.cpp
deleted file mode 100644
index 642f52be425..00000000000
--- a/3rdparty/bx/3rdparty/UnitTest++/src/tests/TestChecks.cpp
+++ /dev/null
@@ -1,293 +0,0 @@
-#include "../UnitTest++.h"
-#include "RecordingReporter.h"
-
-using namespace UnitTest;
-
-
-namespace {
-
-
-TEST(CheckEqualWithUnsignedLong)
-{
- TestResults results;
- unsigned long something = 2;
- CHECK_EQUAL(something, something);
-}
-
-TEST(CheckEqualsWithStringsFailsOnDifferentStrings)
-{
- char txt1[] = "Hello";
- char txt2[] = "Hallo";
- TestResults results;
- CheckEqual(results, txt1, txt2, TestDetails("", "", "", 0));
- CHECK_EQUAL(1, results.GetFailureCount());
-}
-
-char txt1[] = "Hello"; // non-const on purpose so no folding of duplicate data
-char txt2[] = "Hello";
-
-TEST(CheckEqualsWithStringsWorksOnContentsNonConstNonConst)
-{
- char const* const p1 = txt1;
- char const* const p2 = txt2;
- TestResults results;
- CheckEqual(results, p1, p2, TestDetails("", "", "", 0));
- CHECK_EQUAL(0, results.GetFailureCount());
-}
-
-TEST(CheckEqualsWithStringsWorksOnContentsConstConst)
-{
- char* const p1 = txt1;
- char* const p2 = txt2;
- TestResults results;
- CheckEqual(results, p1, p2, TestDetails("", "", "", 0));
- CHECK_EQUAL(0, results.GetFailureCount());
-}
-
-TEST(CheckEqualsWithStringsWorksOnContentsNonConstConst)
-{
- char* const p1 = txt1;
- char const* const p2 = txt2;
- TestResults results;
- CheckEqual(results, p1, p2, TestDetails("", "", "", 0));
- CHECK_EQUAL(0, results.GetFailureCount());
-}
-
-TEST(CheckEqualsWithStringsWorksOnContentsConstNonConst)
-{
- char const* const p1 = txt1;
- char* const p2 = txt2;
- TestResults results;
- CheckEqual(results, p1, p2, TestDetails("", "", "", 0));
- CHECK_EQUAL(0, results.GetFailureCount());
-}
-
-TEST(CheckEqualsWithStringsWorksOnContentsWithALiteral)
-{
- char const* const p1 = txt1;
- TestResults results;
- CheckEqual(results, "Hello", p1, TestDetails("", "", "", 0));
- CHECK_EQUAL(0, results.GetFailureCount());
-}
-
-TEST(CheckEqualFailureIncludesCheckExpectedAndActual)
-{
- RecordingReporter reporter;
- TestResults results(&reporter);
- const int something = 2;
- CheckEqual(results, 1, something, TestDetails("", "", "", 0));
-
- using namespace std;
- CHECK(strstr(reporter.lastFailedMessage, "xpected 1"));
- CHECK(strstr(reporter.lastFailedMessage, "was 2"));
-}
-
-TEST(CheckEqualFailureIncludesDetails)
-{
- RecordingReporter reporter;
- TestResults results(&reporter);
- TestDetails const details("mytest", "mysuite", "file.h", 101);
-
- CheckEqual(results, 1, 2, details);
-
- CHECK_EQUAL("mytest", reporter.lastFailedTest);
- CHECK_EQUAL("mysuite", reporter.lastFailedSuite);
- CHECK_EQUAL("file.h", reporter.lastFailedFile);
- CHECK_EQUAL(101, reporter.lastFailedLine);
-}
-
-TEST(CheckCloseTrue)
-{
- TestResults results;
- CheckClose(results, 3.001f, 3.0f, 0.1f, TestDetails("", "", "", 0));
- CHECK_EQUAL(0, results.GetFailureCount());
-}
-
-TEST(CheckCloseFalse)
-{
- TestResults results;
- CheckClose(results, 3.12f, 3.0f, 0.1f, TestDetails("", "", "", 0));
- CHECK_EQUAL(1, results.GetFailureCount());
-}
-
-TEST(CheckCloseWithZeroEpsilonWorksForSameNumber)
-{
- TestResults results;
- CheckClose(results, 0.1f, 0.1f, 0, TestDetails("", "", "", 0));
- CHECK_EQUAL(0, results.GetFailureCount());
-}
-
-TEST(CheckCloseWithNaNFails)
-{
- union
- {
- unsigned int bitpattern;
- float nan;
- };
- bitpattern = 0xFFFFFFFF;
- TestResults results;
- CheckClose(results, 3.0f, nan, 0.1f, TestDetails("", "", "", 0));
- CHECK_EQUAL(1, results.GetFailureCount());
-}
-
-TEST(CheckCloseWithNaNAgainstItselfFails)
-{
- union
- {
- unsigned int bitpattern;
- float nan;
- };
- bitpattern = 0xFFFFFFFF;
- TestResults results;
- CheckClose(results, nan, nan, 0.1f, TestDetails("", "", "", 0));
- CHECK_EQUAL(1, results.GetFailureCount());
-}
-
-TEST(CheckCloseFailureIncludesCheckExpectedAndActual)
-{
- RecordingReporter reporter;
- TestResults results(&reporter);
- const float expected = 0.9f;
- const float actual = 1.1f;
- CheckClose(results, expected, actual, 0.01f, TestDetails("", "", "", 0));
-
- using namespace std;
- CHECK(strstr(reporter.lastFailedMessage, "xpected 0.9"));
- CHECK(strstr(reporter.lastFailedMessage, "was 1.1"));
-}
-
-TEST(CheckCloseFailureIncludesTolerance)
-{
- RecordingReporter reporter;
- TestResults results(&reporter);
- CheckClose(results, 2, 3, 0.01f, TestDetails("", "", "", 0));
-
- using namespace std;
- CHECK(strstr(reporter.lastFailedMessage, "0.01"));
-}
-
-TEST(CheckCloseFailureIncludesDetails)
-{
- RecordingReporter reporter;
- TestResults results(&reporter);
- TestDetails const details("mytest", "mysuite", "header.h", 10);
-
- CheckClose(results, 2, 3, 0.01f, details);
-
- CHECK_EQUAL("mytest", reporter.lastFailedTest);
- CHECK_EQUAL("mysuite", reporter.lastFailedSuite);
- CHECK_EQUAL("header.h", reporter.lastFailedFile);
- CHECK_EQUAL(10, reporter.lastFailedLine);
-}
-
-
-TEST(CheckArrayEqualTrue)
-{
- TestResults results;
-
- int const array[3] = { 1, 2, 3 };
- CheckArrayEqual(results, array, array, 3, TestDetails("", "", "", 0));
- CHECK_EQUAL(0, results.GetFailureCount());
-}
-
-TEST(CheckArrayEqualFalse)
-{
- TestResults results;
-
- int const array1[3] = { 1, 2, 3 };
- int const array2[3] = { 1, 2, 2 };
- CheckArrayEqual(results, array1, array2, 3, TestDetails("", "", "", 0));
- CHECK_EQUAL(1, results.GetFailureCount());
-}
-
-TEST(CheckArrayCloseTrue)
-{
- TestResults results;
-
- float const array1[3] = { 1.0f, 1.5f, 2.0f };
- float const array2[3] = { 1.01f, 1.51f, 2.01f };
- CheckArrayClose(results, array1, array2, 3, 0.02f, TestDetails("", "", "", 0));
- CHECK_EQUAL(0, results.GetFailureCount());
-}
-
-TEST(CheckArrayCloseFalse)
-{
- TestResults results;
-
- float const array1[3] = { 1.0f, 1.5f, 2.0f };
- float const array2[3] = { 1.01f, 1.51f, 2.01f };
- CheckArrayClose(results, array1, array2, 3, 0.001f, TestDetails("", "", "", 0));
- CHECK_EQUAL(1, results.GetFailureCount());
-}
-
-TEST(CheckArrayCloseFailureIncludesDetails)
-{
- RecordingReporter reporter;
- TestResults results(&reporter);
- TestDetails const details("arrayCloseTest", "arrayCloseSuite", "file", 1337);
-
- float const array1[3] = { 1.0f, 1.5f, 2.0f };
- float const array2[3] = { 1.01f, 1.51f, 2.01f };
- CheckArrayClose(results, array1, array2, 3, 0.001f, details);
-
- CHECK_EQUAL("arrayCloseTest", reporter.lastFailedTest);
- CHECK_EQUAL("arrayCloseSuite", reporter.lastFailedSuite);
- CHECK_EQUAL("file", reporter.lastFailedFile);
- CHECK_EQUAL(1337, reporter.lastFailedLine);
-}
-
-
-TEST(CheckArray2DCloseTrue)
-{
- TestResults results;
-
- float const array1[3][3] = { { 1.0f, 1.5f, 2.0f },
- { 2.0f, 2.5f, 3.0f },
- { 3.0f, 3.5f, 4.0f } };
- float const array2[3][3] = { { 1.01f, 1.51f, 2.01f },
- { 2.01f, 2.51f, 3.01f },
- { 3.01f, 3.51f, 4.01f } };
- CheckArray2DClose(results, array1, array2, 3, 3, 0.02f, TestDetails("", "", "", 0));
- CHECK_EQUAL(0, results.GetFailureCount());
-}
-
-TEST(CheckArray2DCloseFalse)
-{
- TestResults results;
-
- float const array1[3][3] = { { 1.0f, 1.5f, 2.0f },
- { 2.0f, 2.5f, 3.0f },
- { 3.0f, 3.5f, 4.0f } };
- float const array2[3][3] = { { 1.01f, 1.51f, 2.01f },
- { 2.01f, 2.51f, 3.01f },
- { 3.01f, 3.51f, 4.01f } };
- CheckArray2DClose(results, array1, array2, 3, 3, 0.001f, TestDetails("", "", "", 0));
- CHECK_EQUAL(1, results.GetFailureCount());
-}
-
-TEST(CheckCloseWithDoublesSucceeds)
-{
- CHECK_CLOSE(0.5, 0.5, 0.0001);
-}
-
-TEST(CheckArray2DCloseFailureIncludesDetails)
-{
- RecordingReporter reporter;
- TestResults results(&reporter);
- TestDetails const details("array2DCloseTest", "array2DCloseSuite", "file", 1234);
-
- float const array1[3][3] = { { 1.0f, 1.5f, 2.0f },
- { 2.0f, 2.5f, 3.0f },
- { 3.0f, 3.5f, 4.0f } };
- float const array2[3][3] = { { 1.01f, 1.51f, 2.01f },
- { 2.01f, 2.51f, 3.01f },
- { 3.01f, 3.51f, 4.01f } };
- CheckArray2DClose(results, array1, array2, 3, 3, 0.001f, details);
-
- CHECK_EQUAL("array2DCloseTest", reporter.lastFailedTest);
- CHECK_EQUAL("array2DCloseSuite", reporter.lastFailedSuite);
- CHECK_EQUAL("file", reporter.lastFailedFile);
- CHECK_EQUAL(1234, reporter.lastFailedLine);
-}
-
-}
diff --git a/3rdparty/bx/3rdparty/UnitTest++/src/tests/TestCurrentTest.cpp b/3rdparty/bx/3rdparty/UnitTest++/src/tests/TestCurrentTest.cpp
deleted file mode 100644
index a248b31347c..00000000000
--- a/3rdparty/bx/3rdparty/UnitTest++/src/tests/TestCurrentTest.cpp
+++ /dev/null
@@ -1,38 +0,0 @@
-#include "../UnitTest++.h"
-#include "../CurrentTest.h"
-#include "ScopedCurrentTest.h"
-
-namespace
-{
-
-TEST(CanSetandGetDetails)
-{
- bool ok = false;
- {
- ScopedCurrentTest scopedTest;
-
- const UnitTest::TestDetails* details = reinterpret_cast< const UnitTest::TestDetails* >(12345);
- UnitTest::CurrentTest::Details() = details;
-
- ok = (UnitTest::CurrentTest::Details() == details);
- }
-
- CHECK(ok);
-}
-
-TEST(CanSetAndGetResults)
-{
- bool ok = false;
- {
- ScopedCurrentTest scopedTest;
-
- UnitTest::TestResults results;
- UnitTest::CurrentTest::Results() = &results;
-
- ok = (UnitTest::CurrentTest::Results() == &results);
- }
-
- CHECK(ok);
-}
-
-}
diff --git a/3rdparty/bx/3rdparty/UnitTest++/src/tests/TestDeferredTestReporter.cpp b/3rdparty/bx/3rdparty/UnitTest++/src/tests/TestDeferredTestReporter.cpp
deleted file mode 100644
index 2b2b9551f53..00000000000
--- a/3rdparty/bx/3rdparty/UnitTest++/src/tests/TestDeferredTestReporter.cpp
+++ /dev/null
@@ -1,117 +0,0 @@
-#include "../UnitTest++.h"
-#include "../DeferredTestReporter.h"
-#include "../Config.h"
-#include <cstring>
-
-namespace UnitTest
-{
-
-namespace
-{
-
-#ifdef UNITTEST_USE_CUSTOM_STREAMS
- MemoryOutStream& operator <<(MemoryOutStream& lhs, const std::string& rhs)
- {
- lhs << rhs.c_str();
- return lhs;
- }
-#endif
-
-struct MockDeferredTestReporter : public DeferredTestReporter
-{
- virtual void ReportSummary(int, int, int, float)
- {
- }
-};
-
-struct DeferredTestReporterFixture
-{
- DeferredTestReporterFixture()
- : testName("UniqueTestName")
- , testSuite("UniqueTestSuite")
- , fileName("filename.h")
- , lineNumber(12)
- , details(testName.c_str(), testSuite.c_str(), fileName.c_str(), lineNumber)
- {
- }
-
- MockDeferredTestReporter reporter;
- std::string const testName;
- std::string const testSuite;
- std::string const fileName;
- int const lineNumber;
- TestDetails const details;
-};
-
-TEST_FIXTURE(DeferredTestReporterFixture, ReportTestStartCreatesANewDeferredTest)
-{
- reporter.ReportTestStart(details);
- CHECK_EQUAL(1, (int)reporter.GetResults().size());
-}
-
-TEST_FIXTURE(DeferredTestReporterFixture, ReportTestStartCapturesTestNameAndSuite)
-{
- reporter.ReportTestStart(details);
-
- DeferredTestResult const& result = reporter.GetResults().at(0);
- CHECK_EQUAL(testName.c_str(), result.testName);
- CHECK_EQUAL(testSuite.c_str(), result.suiteName);
-}
-
-TEST_FIXTURE(DeferredTestReporterFixture, ReportTestEndCapturesTestTime)
-{
- float const elapsed = 123.45f;
- reporter.ReportTestStart(details);
- reporter.ReportTestFinish(details, elapsed);
-
- DeferredTestResult const& result = reporter.GetResults().at(0);
- CHECK_CLOSE(elapsed, result.timeElapsed, 0.0001f);
-}
-
-TEST_FIXTURE(DeferredTestReporterFixture, ReportFailureSavesFailureDetails)
-{
- char const* failure = "failure";
-
- reporter.ReportTestStart(details);
- reporter.ReportFailure(details, failure);
-
- DeferredTestResult const& result = reporter.GetResults().at(0);
- CHECK(result.failed == true);
- CHECK_EQUAL(fileName.c_str(), result.failureFile);
-}
-
-TEST_FIXTURE(DeferredTestReporterFixture, ReportFailureSavesFailureDetailsForMultipleFailures)
-{
- char const* failure1 = "failure 1";
- char const* failure2 = "failure 2";
-
- reporter.ReportTestStart(details);
- reporter.ReportFailure(details, failure1);
- reporter.ReportFailure(details, failure2);
-
- DeferredTestResult const& result = reporter.GetResults().at(0);
- CHECK_EQUAL(2, (int)result.failures.size());
- CHECK_EQUAL(failure1, result.failures[0].second);
- CHECK_EQUAL(failure2, result.failures[1].second);
-}
-
-TEST_FIXTURE(DeferredTestReporterFixture, DeferredTestReporterTakesCopyOfFailureMessage)
-{
- reporter.ReportTestStart(details);
-
- char failureMessage[128];
- char const* goodStr = "Real failure message";
- char const* badStr = "Bogus failure message";
-
- using namespace std;
-
- strcpy(failureMessage, goodStr);
- reporter.ReportFailure(details, failureMessage);
- strcpy(failureMessage, badStr);
-
- DeferredTestResult const& result = reporter.GetResults().at(0);
- DeferredTestResult::Failure const& failure = result.failures.at(0);
- CHECK_EQUAL(goodStr, failure.second);
-}
-
-}}
diff --git a/3rdparty/bx/3rdparty/UnitTest++/src/tests/TestMemoryOutStream.cpp b/3rdparty/bx/3rdparty/UnitTest++/src/tests/TestMemoryOutStream.cpp
deleted file mode 100644
index 4b7b40e4a84..00000000000
--- a/3rdparty/bx/3rdparty/UnitTest++/src/tests/TestMemoryOutStream.cpp
+++ /dev/null
@@ -1,151 +0,0 @@
-#include "../UnitTest++.h"
-
-#include "../MemoryOutStream.h"
-#include <cstring>
-
-using namespace UnitTest;
-using namespace std;
-
-namespace {
-
-TEST(DefaultIsEmptyString)
-{
- MemoryOutStream const stream;
- CHECK(stream.GetText() != 0);
- CHECK_EQUAL("", stream.GetText());
-}
-
-TEST(StreamingTextCopiesCharacters)
-{
- MemoryOutStream stream;
- stream << "Lalala";
- CHECK_EQUAL("Lalala", stream.GetText());
-}
-
-TEST(StreamingMultipleTimesConcatenatesResult)
-{
- MemoryOutStream stream;
- stream << "Bork" << "Foo" << "Bar";
- CHECK_EQUAL("BorkFooBar", stream.GetText());
-}
-
-TEST(StreamingIntWritesCorrectCharacters)
-{
- MemoryOutStream stream;
- stream << (int)123;
- CHECK_EQUAL("123", stream.GetText());
-}
-
-TEST(StreamingUnsignedIntWritesCorrectCharacters)
-{
- MemoryOutStream stream;
- stream << (unsigned int)123;
- CHECK_EQUAL("123", stream.GetText());
-}
-
-TEST(StreamingLongWritesCorrectCharacters)
-{
- MemoryOutStream stream;
- stream << (long)(-123);
- CHECK_EQUAL("-123", stream.GetText());
-}
-
-TEST(StreamingUnsignedLongWritesCorrectCharacters)
-{
- MemoryOutStream stream;
- stream << (unsigned long)123;
- CHECK_EQUAL("123", stream.GetText());
-}
-
-TEST(StreamingFloatWritesCorrectCharacters)
-{
- MemoryOutStream stream;
- stream << 3.1415f;
- CHECK(strstr(stream.GetText(), "3.1415"));
-}
-
-TEST(StreamingDoubleWritesCorrectCharacters)
-{
- MemoryOutStream stream;
- stream << 3.1415;
- CHECK(strstr(stream.GetText(), "3.1415"));
-}
-
-TEST(StreamingPointerWritesCorrectCharacters)
-{
- MemoryOutStream stream;
- int* p = (int*)0x1234;
- stream << p;
- CHECK(strstr(stream.GetText(), "1234"));
-}
-
-TEST(StreamingSizeTWritesCorrectCharacters)
-{
- MemoryOutStream stream;
- size_t const s = 53124;
- stream << s;
- CHECK_EQUAL("53124", stream.GetText());
-}
-
-#ifdef UNITTEST_USE_CUSTOM_STREAMS
-
-TEST(StreamInitialCapacityIsCorrect)
-{
- MemoryOutStream stream(MemoryOutStream::GROW_CHUNK_SIZE);
- CHECK_EQUAL((int)MemoryOutStream::GROW_CHUNK_SIZE, stream.GetCapacity());
-}
-
-TEST(StreamInitialCapacityIsMultipleOfGrowChunkSize)
-{
- MemoryOutStream stream(MemoryOutStream::GROW_CHUNK_SIZE + 1);
- CHECK_EQUAL((int)MemoryOutStream::GROW_CHUNK_SIZE * 2, stream.GetCapacity());
-}
-
-
-TEST(ExceedingCapacityGrowsBuffer)
-{
- MemoryOutStream stream(MemoryOutStream::GROW_CHUNK_SIZE);
- stream << "012345678901234567890123456789";
- char const* const oldBuffer = stream.GetText();
- stream << "0123456789";
- CHECK(oldBuffer != stream.GetText());
-}
-
-TEST(ExceedingCapacityGrowsBufferByGrowChunk)
-{
- MemoryOutStream stream(MemoryOutStream::GROW_CHUNK_SIZE);
- stream << "0123456789012345678901234567890123456789";
- CHECK_EQUAL(MemoryOutStream::GROW_CHUNK_SIZE * 2, stream.GetCapacity());
-}
-
-TEST(WritingStringLongerThanCapacityFitsInNewBuffer)
-{
- MemoryOutStream stream(8);
- stream << "0123456789ABCDEF";
- CHECK_EQUAL("0123456789ABCDEF", stream.GetText());
-}
-
-TEST(WritingIntLongerThanCapacityFitsInNewBuffer)
-{
- MemoryOutStream stream(8);
- stream << "aaaa" << 123456;;
- CHECK_EQUAL("aaaa123456", stream.GetText());
-}
-
-TEST(WritingFloatLongerThanCapacityFitsInNewBuffer)
-{
- MemoryOutStream stream(8);
- stream << "aaaa" << 123456.0f;;
- CHECK_EQUAL("aaaa123456.000000f", stream.GetText());
-}
-
-TEST(WritingSizeTLongerThanCapacityFitsInNewBuffer)
-{
- MemoryOutStream stream(8);
- stream << "aaaa" << size_t(32145);
- CHECK_EQUAL("aaaa32145", stream.GetText());
-}
-
-#endif
-
-}
diff --git a/3rdparty/bx/3rdparty/UnitTest++/src/tests/TestTest.cpp b/3rdparty/bx/3rdparty/UnitTest++/src/tests/TestTest.cpp
deleted file mode 100644
index fb1f39eca5c..00000000000
--- a/3rdparty/bx/3rdparty/UnitTest++/src/tests/TestTest.cpp
+++ /dev/null
@@ -1,129 +0,0 @@
-#include "../UnitTest++.h"
-#include "../TestReporter.h"
-#include "../TimeHelpers.h"
-#include "ScopedCurrentTest.h"
-
-using namespace UnitTest;
-
-namespace {
-
-TEST(PassingTestHasNoFailures)
-{
- class PassingTest : public Test
- {
- public:
- PassingTest() : Test("passing") {}
- virtual void RunImpl() const
- {
- CHECK(true);
- }
- };
-
- TestResults results;
- {
- ScopedCurrentTest scopedResults(results);
- PassingTest().Run();
- }
-
- CHECK_EQUAL(0, results.GetFailureCount());
-}
-
-
-TEST(FailingTestHasFailures)
-{
- class FailingTest : public Test
- {
- public:
- FailingTest() : Test("failing") {}
- virtual void RunImpl() const
- {
- CHECK(false);
- }
- };
-
- TestResults results;
- {
- ScopedCurrentTest scopedResults(results);
- FailingTest().Run();
- }
-
- CHECK_EQUAL(1, results.GetFailureCount());
-}
-
-
-TEST(ThrowingTestsAreReportedAsFailures)
-{
- class CrashingTest : public Test
- {
- public:
- CrashingTest() : Test("throwing") {}
- virtual void RunImpl() const
- {
- throw "Blah";
- }
- };
-
- TestResults results;
- {
- ScopedCurrentTest scopedResult(results);
- CrashingTest().Run();
- }
-
- CHECK_EQUAL(1, results.GetFailureCount());
-}
-
-
-#ifndef UNITTEST_MINGW
-TEST(CrashingTestsAreReportedAsFailures)
-{
- class CrashingTest : public Test
- {
- public:
- CrashingTest() : Test("crashing") {}
- virtual void RunImpl() const
- {
- reinterpret_cast< void (*)() >(0)();
- }
- };
-
- TestResults results;
- {
- ScopedCurrentTest scopedResult(results);
- CrashingTest().Run();
- }
-
- CHECK_EQUAL(1, results.GetFailureCount());
-}
-#endif
-
-TEST(TestWithUnspecifiedSuiteGetsDefaultSuite)
-{
- Test test("test");
- CHECK(test.m_details.suiteName != NULL);
- CHECK_EQUAL("DefaultSuite", test.m_details.suiteName);
-}
-
-TEST(TestReflectsSpecifiedSuiteName)
-{
- Test test("test", "testSuite");
- CHECK(test.m_details.suiteName != NULL);
- CHECK_EQUAL("testSuite", test.m_details.suiteName);
-}
-
-void Fail()
-{
- CHECK(false);
-}
-
-TEST(OutOfCoreCHECKMacrosCanFailTests)
-{
- TestResults results;
- {
- ScopedCurrentTest scopedResult(results);
- Fail();
- }
-
- CHECK_EQUAL(1, results.GetFailureCount());
-}
-
-}
diff --git a/3rdparty/bx/3rdparty/UnitTest++/src/tests/TestTestList.cpp b/3rdparty/bx/3rdparty/UnitTest++/src/tests/TestTestList.cpp
deleted file mode 100644
index 1498ad7a69d..00000000000
--- a/3rdparty/bx/3rdparty/UnitTest++/src/tests/TestTestList.cpp
+++ /dev/null
@@ -1,50 +0,0 @@
-#include "../UnitTest++.h"
-#include "../TestList.h"
-
-using namespace UnitTest;
-
-namespace {
-
-
-TEST (TestListIsEmptyByDefault)
-{
- TestList list;
- CHECK (list.GetHead() == 0);
-}
-
-TEST (AddingTestSetsHeadToTest)
-{
- Test test("test");
- TestList list;
- list.Add(&test);
-
- CHECK (list.GetHead() == &test);
- CHECK (test.next == 0);
-}
-
-TEST (AddingSecondTestAddsItToEndOfList)
-{
- Test test1("test1");
- Test test2("test2");
-
- TestList list;
- list.Add(&test1);
- list.Add(&test2);
-
- CHECK (list.GetHead() == &test1);
- CHECK (test1.next == &test2);
- CHECK (test2.next == 0);
-}
-
-TEST (ListAdderAddsTestToList)
-{
- TestList list;
-
- Test test("");
- ListAdder adder(list, &test);
-
- CHECK (list.GetHead() == &test);
- CHECK (test.next == 0);
-}
-
-}
diff --git a/3rdparty/bx/3rdparty/UnitTest++/src/tests/TestTestMacros.cpp b/3rdparty/bx/3rdparty/UnitTest++/src/tests/TestTestMacros.cpp
deleted file mode 100644
index 8fd7778394e..00000000000
--- a/3rdparty/bx/3rdparty/UnitTest++/src/tests/TestTestMacros.cpp
+++ /dev/null
@@ -1,212 +0,0 @@
-#include "../UnitTest++.h"
-#include "../TestMacros.h"
-#include "../TestList.h"
-#include "../TestResults.h"
-#include "../TestReporter.h"
-#include "../ReportAssert.h"
-#include "RecordingReporter.h"
-#include "ScopedCurrentTest.h"
-
-using namespace UnitTest;
-
-namespace {
-
-TestList list1;
-TEST_EX(DummyTest, list1)
-{
-}
-
-TEST (TestsAreAddedToTheListThroughMacro)
-{
- CHECK(list1.GetHead() != 0);
- CHECK(list1.GetHead()->next == 0);
-}
-
-struct ThrowingThingie
-{
- ThrowingThingie() : dummy(false)
- {
- if (!dummy)
- throw "Oops";
- }
-
- bool dummy;
-};
-
-TestList list2;
-TEST_FIXTURE_EX(ThrowingThingie, DummyTestName, list2)
-{
-}
-
-TEST (ExceptionsInFixtureAreReportedAsHappeningInTheFixture)
-{
- RecordingReporter reporter;
- TestResults result(&reporter);
- {
- ScopedCurrentTest scopedResults(result);
- list2.GetHead()->Run();
- }
-
- CHECK(strstr(reporter.lastFailedMessage, "xception"));
- CHECK(strstr(reporter.lastFailedMessage, "fixture"));
- CHECK(strstr(reporter.lastFailedMessage, "ThrowingThingie"));
-}
-
-struct DummyFixture
-{
- int x;
-};
-
-// We're really testing the macros so we just want them to compile and link
-SUITE(TestSuite1)
-{
- TEST(SimilarlyNamedTestsInDifferentSuitesWork)
- {
- }
-
- TEST_FIXTURE(DummyFixture, SimilarlyNamedFixtureTestsInDifferentSuitesWork)
- {
- }
-}
-
-SUITE(TestSuite2)
-{
- TEST(SimilarlyNamedTestsInDifferentSuitesWork)
- {
- }
-
- TEST_FIXTURE(DummyFixture,SimilarlyNamedFixtureTestsInDifferentSuitesWork)
- {
- }
-}
-
-TestList macroTestList1;
-TEST_EX(MacroTestHelper1, macroTestList1)
-{
-}
-
-TEST(TestAddedWithTEST_EXMacroGetsDefaultSuite)
-{
- CHECK(macroTestList1.GetHead() != NULL);
- CHECK_EQUAL ("MacroTestHelper1", macroTestList1.GetHead()->m_details.testName);
- CHECK_EQUAL ("DefaultSuite", macroTestList1.GetHead()->m_details.suiteName);
-}
-
-TestList macroTestList2;
-TEST_FIXTURE_EX(DummyFixture, MacroTestHelper2, macroTestList2)
-{
-}
-
-TEST(TestAddedWithTEST_FIXTURE_EXMacroGetsDefaultSuite)
-{
- CHECK(macroTestList2.GetHead() != NULL);
- CHECK_EQUAL ("MacroTestHelper2", macroTestList2.GetHead()->m_details.testName);
- CHECK_EQUAL ("DefaultSuite", macroTestList2.GetHead()->m_details.suiteName);
-}
-
-struct FixtureCtorThrows
-{
- FixtureCtorThrows() { throw "exception"; }
-};
-
-TestList throwingFixtureTestList1;
-TEST_FIXTURE_EX(FixtureCtorThrows, FixtureCtorThrowsTestName, throwingFixtureTestList1)
-{
-}
-
-TEST(FixturesWithThrowingCtorsAreFailures)
-{
- CHECK(throwingFixtureTestList1.GetHead() != NULL);
- RecordingReporter reporter;
- TestResults result(&reporter);
- {
- ScopedCurrentTest scopedResult(result);
- throwingFixtureTestList1.GetHead()->Run();
- }
-
- int const failureCount = result.GetFailedTestCount();
- CHECK_EQUAL(1, failureCount);
- CHECK(strstr(reporter.lastFailedMessage, "while constructing fixture"));
-}
-
-struct FixtureDtorThrows
-{
- ~FixtureDtorThrows() { throw "exception"; }
-};
-
-TestList throwingFixtureTestList2;
-TEST_FIXTURE_EX(FixtureDtorThrows, FixtureDtorThrowsTestName, throwingFixtureTestList2)
-{
-}
-
-TEST(FixturesWithThrowingDtorsAreFailures)
-{
- CHECK(throwingFixtureTestList2.GetHead() != NULL);
-
- RecordingReporter reporter;
- TestResults result(&reporter);
- {
- ScopedCurrentTest scopedResult(result);
- throwingFixtureTestList2.GetHead()->Run();
- }
-
- int const failureCount = result.GetFailedTestCount();
- CHECK_EQUAL(1, failureCount);
- CHECK(strstr(reporter.lastFailedMessage, "while destroying fixture"));
-}
-
-const int FailingLine = 123;
-
-struct FixtureCtorAsserts
-{
- FixtureCtorAsserts()
- {
- UnitTest::ReportAssert("assert failure", "file", FailingLine);
- }
-};
-
-TestList ctorAssertFixtureTestList;
-TEST_FIXTURE_EX(FixtureCtorAsserts, CorrectlyReportsAssertFailureInCtor, ctorAssertFixtureTestList)
-{
-}
-
-TEST(CorrectlyReportsFixturesWithCtorsThatAssert)
-{
- RecordingReporter reporter;
- TestResults result(&reporter);
- {
- ScopedCurrentTest scopedResults(result);
- ctorAssertFixtureTestList.GetHead()->Run();
- }
-
- const int failureCount = result.GetFailedTestCount();
- CHECK_EQUAL(1, failureCount);
- CHECK_EQUAL(FailingLine, reporter.lastFailedLine);
- CHECK(strstr(reporter.lastFailedMessage, "assert failure"));
-}
-
-}
-
-// We're really testing if it's possible to use the same suite in two files
-// to compile and link successfuly (TestTestSuite.cpp has suite with the same name)
-// Note: we are outside of the anonymous namespace
-SUITE(SameTestSuite)
-{
- TEST(DummyTest1)
- {
- }
-}
-
-#define CUR_TEST_NAME CurrentTestDetailsContainCurrentTestInfo
-#define INNER_STRINGIFY(X) #X
-#define STRINGIFY(X) INNER_STRINGIFY(X)
-
-TEST(CUR_TEST_NAME)
-{
- const UnitTest::TestDetails* details = CurrentTest::Details();
- CHECK_EQUAL(STRINGIFY(CUR_TEST_NAME), details->testName);
-}
-
-#undef CUR_TEST_NAME
-#undef INNER_STRINGIFY
-#undef STRINGIFY
diff --git a/3rdparty/bx/3rdparty/UnitTest++/src/tests/TestTestResults.cpp b/3rdparty/bx/3rdparty/UnitTest++/src/tests/TestTestResults.cpp
deleted file mode 100644
index 65efbff7aa6..00000000000
--- a/3rdparty/bx/3rdparty/UnitTest++/src/tests/TestTestResults.cpp
+++ /dev/null
@@ -1,111 +0,0 @@
-#include "../UnitTest++.h"
-#include "../TestResults.h"
-#include "RecordingReporter.h"
-
-using namespace UnitTest;
-
-namespace {
-
-TestDetails const details("testname", "suitename", "filename", 123);
-
-
-TEST(StartsWithNoTestsRun)
-{
- TestResults results;
- CHECK_EQUAL (0, results.GetTotalTestCount());
-}
-
-TEST(RecordsNumbersOfTests)
-{
- TestResults results;
- results.OnTestStart(details);
- results.OnTestStart(details);
- results.OnTestStart(details);
- CHECK_EQUAL(3, results.GetTotalTestCount());
-}
-
-TEST(StartsWithNoTestsFailing)
-{
- TestResults results;
- CHECK_EQUAL (0, results.GetFailureCount());
-}
-
-TEST(RecordsNumberOfFailures)
-{
- TestResults results;
- results.OnTestFailure(details, "");
- results.OnTestFailure(details, "");
- CHECK_EQUAL(2, results.GetFailureCount());
-}
-
-TEST(RecordsNumberOfFailedTests)
-{
- TestResults results;
-
- results.OnTestStart(details);
- results.OnTestFailure(details, "");
- results.OnTestFinish(details, 0);
-
- results.OnTestStart(details);
- results.OnTestFailure(details, "");
- results.OnTestFailure(details, "");
- results.OnTestFailure(details, "");
- results.OnTestFinish(details, 0);
-
- CHECK_EQUAL (2, results.GetFailedTestCount());
-}
-
-TEST(NotifiesReporterOfTestStartWithCorrectInfo)
-{
- RecordingReporter reporter;
- TestResults results(&reporter);
- results.OnTestStart(details);
-
- CHECK_EQUAL (1, reporter.testRunCount);
- CHECK_EQUAL ("suitename", reporter.lastStartedSuite);
- CHECK_EQUAL ("testname", reporter.lastStartedTest);
-}
-
-TEST(NotifiesReporterOfTestFailureWithCorrectInfo)
-{
- RecordingReporter reporter;
- TestResults results(&reporter);
-
- results.OnTestFailure(details, "failurestring");
- CHECK_EQUAL (1, reporter.testFailedCount);
- CHECK_EQUAL ("filename", reporter.lastFailedFile);
- CHECK_EQUAL (123, reporter.lastFailedLine);
- CHECK_EQUAL ("suitename", reporter.lastFailedSuite);
- CHECK_EQUAL ("testname", reporter.lastFailedTest);
- CHECK_EQUAL ("failurestring", reporter.lastFailedMessage);
-}
-
-TEST(NotifiesReporterOfCheckFailureWithCorrectInfo)
-{
- RecordingReporter reporter;
- TestResults results(&reporter);
-
- results.OnTestFailure(details, "failurestring");
- CHECK_EQUAL (1, reporter.testFailedCount);
-
- CHECK_EQUAL ("filename", reporter.lastFailedFile);
- CHECK_EQUAL (123, reporter.lastFailedLine);
- CHECK_EQUAL ("testname", reporter.lastFailedTest);
- CHECK_EQUAL ("suitename", reporter.lastFailedSuite);
- CHECK_EQUAL ("failurestring", reporter.lastFailedMessage);
-}
-
-TEST(NotifiesReporterOfTestEnd)
-{
- RecordingReporter reporter;
- TestResults results(&reporter);
-
- results.OnTestFinish(details, 0.1234f);
- CHECK_EQUAL (1, reporter.testFinishedCount);
- CHECK_EQUAL ("testname", reporter.lastFinishedTest);
- CHECK_EQUAL ("suitename", reporter.lastFinishedSuite);
- CHECK_CLOSE (0.1234f, reporter.lastFinishedTestTime, 0.0001f);
-}
-
-
-}
diff --git a/3rdparty/bx/3rdparty/UnitTest++/src/tests/TestTestRunner.cpp b/3rdparty/bx/3rdparty/UnitTest++/src/tests/TestTestRunner.cpp
deleted file mode 100644
index ad35d2c0c8e..00000000000
--- a/3rdparty/bx/3rdparty/UnitTest++/src/tests/TestTestRunner.cpp
+++ /dev/null
@@ -1,307 +0,0 @@
-#include "../UnitTest++.h"
-#include "RecordingReporter.h"
-#include "../ReportAssert.h"
-#include "../TestList.h"
-#include "../TimeHelpers.h"
-#include "../TimeConstraint.h"
-
-using namespace UnitTest;
-
-namespace
-{
-
-struct MockTest : public Test
-{
- MockTest(char const* testName, bool const success_, bool const assert_, int const count_ = 1)
- : Test(testName)
- , success(success_)
- , asserted(assert_)
- , count(count_)
- {
- }
-
- virtual void RunImpl(TestResults& testResults_) const
- {
- for (int i=0; i < count; ++i)
- {
- if (asserted)
- ReportAssert("desc", "file", 0);
- else if (!success)
- testResults_.OnTestFailure(m_details, "message");
- }
- }
-
- bool const success;
- bool const asserted;
- int const count;
-};
-
-
-struct TestRunnerFixture
-{
- TestRunnerFixture()
- : runner(reporter)
- {
- }
-
- RecordingReporter reporter;
- TestList list;
- TestRunner runner;
-};
-
-TEST_FIXTURE(TestRunnerFixture, TestStartIsReportedCorrectly)
-{
- MockTest test("goodtest", true, false);
- list.Add(&test);
-
- runner.RunTestsIf(list, NULL, True(), 0);
- CHECK_EQUAL(1, reporter.testRunCount);
- CHECK_EQUAL("goodtest", reporter.lastStartedTest);
-}
-
-TEST_FIXTURE(TestRunnerFixture, TestFinishIsReportedCorrectly)
-{
- MockTest test("goodtest", true, false);
- list.Add(&test);
-
- runner.RunTestsIf(list, NULL, True(), 0);
- CHECK_EQUAL(1, reporter.testFinishedCount);
- CHECK_EQUAL("goodtest", reporter.lastFinishedTest);
-}
-
-class SlowTest : public Test
-{
-public:
- SlowTest() : Test("slow", "somesuite", "filename", 123) {}
- virtual void RunImpl(TestResults&) const
- {
- TimeHelpers::SleepMs(20);
- }
-};
-
-TEST_FIXTURE(TestRunnerFixture, TestFinishIsCalledWithCorrectTime)
-{
- SlowTest test;
- list.Add(&test);
-
- runner.RunTestsIf(list, NULL, True(), 0);
- CHECK(reporter.lastFinishedTestTime >= 0.005f && reporter.lastFinishedTestTime <= 0.050f);
-}
-
-TEST_FIXTURE(TestRunnerFixture, FailureCountIsZeroWhenNoTestsAreRun)
-{
- CHECK_EQUAL(0, runner.RunTestsIf(list, NULL, True(), 0));
- CHECK_EQUAL(0, reporter.testRunCount);
- CHECK_EQUAL(0, reporter.testFailedCount);
-}
-
-TEST_FIXTURE(TestRunnerFixture, CallsReportFailureOncePerFailingTest)
-{
- MockTest test1("test", false, false);
- list.Add(&test1);
- MockTest test2("test", true, false);
- list.Add(&test2);
- MockTest test3("test", false, false);
- list.Add(&test3);
-
- CHECK_EQUAL(2, runner.RunTestsIf(list, NULL, True(), 0));
- CHECK_EQUAL(2, reporter.testFailedCount);
-}
-
-TEST_FIXTURE(TestRunnerFixture, TestsThatAssertAreReportedAsFailing)
-{
- MockTest test("test", true, true);
- list.Add(&test);
-
- runner.RunTestsIf(list, NULL, True(), 0);
- CHECK_EQUAL(1, reporter.testFailedCount);
-}
-
-
-TEST_FIXTURE(TestRunnerFixture, ReporterNotifiedOfTestCount)
-{
- MockTest test1("test", true, false);
- MockTest test2("test", true, false);
- MockTest test3("test", true, false);
- list.Add(&test1);
- list.Add(&test2);
- list.Add(&test3);
-
- runner.RunTestsIf(list, NULL, True(), 0);
- CHECK_EQUAL(3, reporter.summaryTotalTestCount);
-}
-
-TEST_FIXTURE(TestRunnerFixture, ReporterNotifiedOfFailedTests)
-{
- MockTest test1("test", false, false, 2);
- MockTest test2("test", true, false);
- MockTest test3("test", false, false, 3);
- list.Add(&test1);
- list.Add(&test2);
- list.Add(&test3);
-
- runner.RunTestsIf(list, NULL, True(), 0);
- CHECK_EQUAL(2, reporter.summaryFailedTestCount);
-}
-
-TEST_FIXTURE(TestRunnerFixture, ReporterNotifiedOfFailures)
-{
- MockTest test1("test", false, false, 2);
- MockTest test2("test", true, false);
- MockTest test3("test", false, false, 3);
- list.Add(&test1);
- list.Add(&test2);
- list.Add(&test3);
-
- runner.RunTestsIf(list, NULL, True(), 0);
- CHECK_EQUAL(5, reporter.summaryFailureCount);
-}
-
-TEST_FIXTURE(TestRunnerFixture, SlowTestPassesForHighTimeThreshold)
-{
- SlowTest test;
- list.Add(&test);
-
- runner.RunTestsIf(list, NULL, True(), 0);
- CHECK_EQUAL(0, reporter.testFailedCount);
-}
-
-TEST_FIXTURE(TestRunnerFixture, SlowTestFailsForLowTimeThreshold)
-{
- SlowTest test;
- list.Add(&test);
-
- runner.RunTestsIf(list, NULL, True(), 3);
- CHECK_EQUAL(1, reporter.testFailedCount);
-}
-
-TEST_FIXTURE(TestRunnerFixture, SlowTestHasCorrectFailureInformation)
-{
- SlowTest test;
- list.Add(&test);
-
- runner.RunTestsIf(list, NULL, True(), 3);
-
- using namespace std;
-
- CHECK_EQUAL(test.m_details.testName, reporter.lastFailedTest);
- CHECK(strstr(test.m_details.filename, reporter.lastFailedFile));
- CHECK_EQUAL(test.m_details.lineNumber, reporter.lastFailedLine);
-
- CHECK(strstr(reporter.lastFailedMessage, "Global time constraint failed"));
- CHECK(strstr(reporter.lastFailedMessage, "3ms"));
-}
-
-TEST_FIXTURE(TestRunnerFixture, SlowTestWithTimeExemptionPasses)
-{
- class SlowExemptedTest : public Test
- {
- public:
- SlowExemptedTest() : Test("slowexempted", "", 0) {}
- virtual void RunImpl(TestResults&) const
- {
- UNITTEST_TIME_CONSTRAINT_EXEMPT();
- TimeHelpers::SleepMs(20);
- }
- };
-
- SlowExemptedTest test;
- list.Add(&test);
-
- runner.RunTestsIf(list, NULL, True(), 3);
- CHECK_EQUAL(0, reporter.testFailedCount);
-}
-
-struct TestSuiteFixture
-{
- TestSuiteFixture()
- : test1("TestInDefaultSuite")
- , test2("TestInOtherSuite", "OtherSuite")
- , test3("SecondTestInDefaultSuite")
- , runner(reporter)
- {
- list.Add(&test1);
- list.Add(&test2);
- }
-
- Test test1;
- Test test2;
- Test test3;
- RecordingReporter reporter;
- TestList list;
- TestRunner runner;
-};
-
-TEST_FIXTURE(TestSuiteFixture, TestRunnerRunsAllSuitesIfNullSuiteIsPassed)
-{
- runner.RunTestsIf(list, NULL, True(), 0);
- CHECK_EQUAL(2, reporter.summaryTotalTestCount);
-}
-
-TEST_FIXTURE(TestSuiteFixture,TestRunnerRunsOnlySpecifiedSuite)
-{
- runner.RunTestsIf(list, "OtherSuite", True(), 0);
- CHECK_EQUAL(1, reporter.summaryTotalTestCount);
- CHECK_EQUAL("TestInOtherSuite", reporter.lastFinishedTest);
-}
-
-struct RunTestIfNameIs
-{
- RunTestIfNameIs(char const* name_)
- : name(name_)
- {
- }
-
- bool operator()(const Test* const test) const
- {
- using namespace std;
- return (0 == strcmp(test->m_details.testName, name));
- }
-
- char const* name;
-};
-
-TEST(TestMockPredicateBehavesCorrectly)
-{
- RunTestIfNameIs predicate("pass");
-
- Test pass("pass");
- Test fail("fail");
-
- CHECK(predicate(&pass));
- CHECK(!predicate(&fail));
-}
-
-TEST_FIXTURE(TestRunnerFixture, TestRunnerRunsTestsThatPassPredicate)
-{
- Test should_run("goodtest");
- list.Add(&should_run);
-
- Test should_not_run("badtest");
- list.Add(&should_not_run);
-
- runner.RunTestsIf(list, NULL, RunTestIfNameIs("goodtest"), 0);
- CHECK_EQUAL(1, reporter.testRunCount);
- CHECK_EQUAL("goodtest", reporter.lastStartedTest);
-}
-
-TEST_FIXTURE(TestRunnerFixture, TestRunnerOnlyRunsTestsInSpecifiedSuiteAndThatPassPredicate)
-{
- Test runningTest1("goodtest", "suite");
- Test skippedTest2("goodtest");
- Test skippedTest3("badtest", "suite");
- Test skippedTest4("badtest");
-
- list.Add(&runningTest1);
- list.Add(&skippedTest2);
- list.Add(&skippedTest3);
- list.Add(&skippedTest4);
-
- runner.RunTestsIf(list, "suite", RunTestIfNameIs("goodtest"), 0);
-
- CHECK_EQUAL(1, reporter.testRunCount);
- CHECK_EQUAL("goodtest", reporter.lastStartedTest);
- CHECK_EQUAL("suite", reporter.lastStartedSuite);
-}
-
-}
diff --git a/3rdparty/bx/3rdparty/UnitTest++/src/tests/TestTestSuite.cpp b/3rdparty/bx/3rdparty/UnitTest++/src/tests/TestTestSuite.cpp
deleted file mode 100644
index 9b29e43e3c6..00000000000
--- a/3rdparty/bx/3rdparty/UnitTest++/src/tests/TestTestSuite.cpp
+++ /dev/null
@@ -1,12 +0,0 @@
-#include "../UnitTest++.h"
-
-// We're really testing if it's possible to use the same suite in two files
-// to compile and link successfuly (TestTestSuite.cpp has suite with the same name)
-// Note: we are outside of the anonymous namespace
-SUITE(SameTestSuite)
-{
- TEST(DummyTest2)
- {
- }
-}
-
diff --git a/3rdparty/bx/3rdparty/UnitTest++/src/tests/TestTimeConstraint.cpp b/3rdparty/bx/3rdparty/UnitTest++/src/tests/TestTimeConstraint.cpp
deleted file mode 100644
index c424160c388..00000000000
--- a/3rdparty/bx/3rdparty/UnitTest++/src/tests/TestTimeConstraint.cpp
+++ /dev/null
@@ -1,69 +0,0 @@
-#include "../UnitTest++.h"
-#include "../TestResults.h"
-#include "../TimeHelpers.h"
-#include "RecordingReporter.h"
-#include "ScopedCurrentTest.h"
-
-using namespace UnitTest;
-
-namespace
-{
-
-TEST(TimeConstraintSucceedsWithFastTest)
-{
- TestResults result;
- {
- ScopedCurrentTest scopedResult(result);
- TimeConstraint t(200, TestDetails("", "", "", 0));
- TimeHelpers::SleepMs(5);
- }
- CHECK_EQUAL(0, result.GetFailureCount());
-}
-
-TEST(TimeConstraintFailsWithSlowTest)
-{
- TestResults result;
- {
- ScopedCurrentTest scopedResult(result);
- TimeConstraint t(10, TestDetails("", "", "", 0));
- TimeHelpers::SleepMs(20);
- }
- CHECK_EQUAL(1, result.GetFailureCount());
-}
-
-TEST(TimeConstraintFailureIncludesCorrectData)
-{
- RecordingReporter reporter;
- TestResults result(&reporter);
- {
- ScopedCurrentTest scopedResult(result);
-
- TestDetails const details("testname", "suitename", "filename", 10);
- TimeConstraint t(10, details);
- TimeHelpers::SleepMs(20);
- }
-
- using namespace std;
-
- CHECK(strstr(reporter.lastFailedFile, "filename"));
- CHECK_EQUAL(10, reporter.lastFailedLine);
- CHECK(strstr(reporter.lastFailedTest, "testname"));
-}
-
-TEST(TimeConstraintFailureIncludesTimeoutInformation)
-{
- RecordingReporter reporter;
- TestResults result(&reporter);
- {
- ScopedCurrentTest scopedResult(result);
- TimeConstraint t(10, TestDetails("", "", "", 0));
- TimeHelpers::SleepMs(20);
- }
-
- using namespace std;
-
- CHECK(strstr(reporter.lastFailedMessage, "ime constraint"));
- CHECK(strstr(reporter.lastFailedMessage, "under 10ms"));
-}
-
-}
diff --git a/3rdparty/bx/3rdparty/UnitTest++/src/tests/TestTimeConstraintMacro.cpp b/3rdparty/bx/3rdparty/UnitTest++/src/tests/TestTimeConstraintMacro.cpp
deleted file mode 100644
index 785c6ce7486..00000000000
--- a/3rdparty/bx/3rdparty/UnitTest++/src/tests/TestTimeConstraintMacro.cpp
+++ /dev/null
@@ -1,65 +0,0 @@
-#include "../UnitTest++.h"
-#include "../TimeHelpers.h"
-
-#include "RecordingReporter.h"
-#include "ScopedCurrentTest.h"
-
-namespace {
-
-TEST(TimeConstraintMacroQualifiesNamespace)
-{
- // If this compiles without a "using namespace UnitTest;", all is well.
- UNITTEST_TIME_CONSTRAINT(1);
-}
-
-TEST(TimeConstraintMacroUsesCorrectInfo)
-{
- int testLine = 0;
- RecordingReporter reporter;
-
- {
- UnitTest::TestResults testResults(&reporter);
- ScopedCurrentTest scopedResults(testResults);
-
- UNITTEST_TIME_CONSTRAINT(10); testLine = __LINE__;
- UnitTest::TimeHelpers::SleepMs(20);
- }
-
- using namespace std;
-
- CHECK_EQUAL(1, reporter.testFailedCount);
- CHECK(strstr(reporter.lastFailedFile, __FILE__));
- CHECK_EQUAL(testLine, reporter.lastFailedLine);
- CHECK(strstr(reporter.lastFailedTest, "TimeConstraintMacroUsesCorrectInfo"));
-}
-
-TEST(TimeConstraintMacroComparesAgainstPreciseActual)
-{
- int testLine = 0;
- RecordingReporter reporter;
-
- {
- UnitTest::TestResults testResults(&reporter);
- ScopedCurrentTest scopedResults(testResults);
-
- UNITTEST_TIME_CONSTRAINT(1); testLine = __LINE__;
-
- // start a new timer and run until we're as little over the 1 msec
- // threshold as we can achieve; this should guarantee that the "test"
- // runs in some very small amount of time > 1 msec
- UnitTest::Timer myTimer;
- myTimer.Start();
-
- while (myTimer.GetTimeInMs() < 1.001)
- UnitTest::TimeHelpers::SleepMs(0);
- }
-
- using namespace std;
-
- CHECK_EQUAL(1, reporter.testFailedCount);
- CHECK(strstr(reporter.lastFailedFile, __FILE__));
- CHECK_EQUAL(testLine, reporter.lastFailedLine);
- CHECK(strstr(reporter.lastFailedTest, "TimeConstraintMacroComparesAgainstPreciseActual"));
-}
-
-}
diff --git a/3rdparty/bx/3rdparty/UnitTest++/src/tests/TestUnitTest++.cpp b/3rdparty/bx/3rdparty/UnitTest++/src/tests/TestUnitTest++.cpp
deleted file mode 100644
index 4755e5e24bf..00000000000
--- a/3rdparty/bx/3rdparty/UnitTest++/src/tests/TestUnitTest++.cpp
+++ /dev/null
@@ -1,156 +0,0 @@
-#include "../UnitTest++.h"
-#include "../ReportAssert.h"
-#include "ScopedCurrentTest.h"
-
-#include <vector>
-
-// These are sample tests that show the different features of the framework
-
-namespace {
-
-TEST(ValidCheckSucceeds)
-{
- bool const b = true;
- CHECK(b);
-}
-
-TEST(CheckWorksWithPointers)
-{
- void* p = (void *)0x100;
- CHECK(p);
- CHECK(p != 0);
-}
-
-TEST(ValidCheckEqualSucceeds)
-{
- int const x = 3;
- int const y = 3;
- CHECK_EQUAL(x, y);
-}
-
-TEST(CheckEqualWorksWithPointers)
-{
- void* p = (void *)0;
- CHECK_EQUAL((void*)0, p);
-}
-
-TEST(ValidCheckCloseSucceeds)
-{
- CHECK_CLOSE(2.0f, 2.001f, 0.01f);
- CHECK_CLOSE(2.001f, 2.0f, 0.01f);
-}
-
-TEST(ArrayCloseSucceeds)
-{
- float const a1[] = {1, 2, 3};
- float const a2[] = {1, 2.01f, 3};
- CHECK_ARRAY_CLOSE(a1, a2, 3, 0.1f);
-}
-
-TEST (CheckArrayCloseWorksWithVectors)
-{
- std::vector< float > a(4);
- for (int i = 0; i < 4; ++i)
- a[i] = (float)i;
-
- CHECK_ARRAY_CLOSE(a, a, (int)a.size(), 0.0001f);
-}
-
-TEST(CheckThrowMacroSucceedsOnCorrectException)
-{
- struct TestException {};
- CHECK_THROW(throw TestException(), TestException);
-}
-
-TEST(CheckAssertSucceeds)
-{
- CHECK_ASSERT(UnitTest::ReportAssert("desc", "file", 0));
-}
-
-TEST(CheckThrowMacroFailsOnMissingException)
-{
- class NoThrowTest : public UnitTest::Test
- {
- public:
- NoThrowTest() : Test("nothrow") {}
- void DontThrow() const
- {
- }
-
- virtual void RunImpl() const
- {
- CHECK_THROW(DontThrow(), int);
- }
- };
-
- UnitTest::TestResults results;
- {
- ScopedCurrentTest scopedResults(results);
-
- NoThrowTest test;
- test.Run();
- }
-
- CHECK_EQUAL(1, results.GetFailureCount());
-}
-
-TEST(CheckThrowMacroFailsOnWrongException)
-{
- class WrongThrowTest : public UnitTest::Test
- {
- public:
- WrongThrowTest() : Test("wrongthrow") {}
- virtual void RunImpl() const
- {
- CHECK_THROW(throw "oops", int);
- }
- };
-
- UnitTest::TestResults results;
- {
- ScopedCurrentTest scopedResults(results);
-
- WrongThrowTest test;
- test.Run();
- }
-
- CHECK_EQUAL(1, results.GetFailureCount());
-}
-
-struct SimpleFixture
-{
- SimpleFixture()
- {
- ++instanceCount;
- }
- ~SimpleFixture()
- {
- --instanceCount;
- }
-
- static int instanceCount;
-};
-
-int SimpleFixture::instanceCount = 0;
-
-TEST_FIXTURE(SimpleFixture, DefaultFixtureCtorIsCalled)
-{
- CHECK(SimpleFixture::instanceCount > 0);
-}
-
-TEST_FIXTURE(SimpleFixture, OnlyOneFixtureAliveAtATime)
-{
- CHECK_EQUAL(1, SimpleFixture::instanceCount);
-}
-
-void CheckBool(const bool b)
-{
- CHECK(b);
-}
-
-TEST(CanCallCHECKOutsideOfTestFunction)
-{
- CheckBool(true);
-}
-
-}
diff --git a/3rdparty/bx/3rdparty/UnitTest++/src/tests/TestXmlTestReporter.cpp b/3rdparty/bx/3rdparty/UnitTest++/src/tests/TestXmlTestReporter.cpp
deleted file mode 100644
index a63abb8c05b..00000000000
--- a/3rdparty/bx/3rdparty/UnitTest++/src/tests/TestXmlTestReporter.cpp
+++ /dev/null
@@ -1,183 +0,0 @@
-#include "../UnitTest++.h"
-#include "../XmlTestReporter.h"
-
-#include <sstream>
-
-using namespace UnitTest;
-using std::ostringstream;
-
-namespace
-{
-
-#ifdef UNITTEST_USE_CUSTOM_STREAMS
-
-// Overload to let MemoryOutStream accept std::string
-MemoryOutStream& operator<<(MemoryOutStream& s, const std::string& value)
-{
- s << value.c_str();
- return s;
-}
-
-#endif
-
-struct XmlTestReporterFixture
-{
- XmlTestReporterFixture()
- : reporter(output)
- {
- }
-
- ostringstream output;
- XmlTestReporter reporter;
-};
-
-TEST_FIXTURE(XmlTestReporterFixture, MultipleCharactersAreEscaped)
-{
- TestDetails const details("TestName", "suite", "filename.h", 4321);
-
- reporter.ReportTestStart(details);
- reporter.ReportFailure(details, "\"\"\'\'&&<<>>");
- reporter.ReportTestFinish(details, 0.1f);
- reporter.ReportSummary(1, 2, 3, 0.1f);
-
- char const* expected =
- "<?xml version=\"1.0\"?>"
- "<unittest-results tests=\"1\" failedtests=\"2\" failures=\"3\" time=\"0.1\">"
- "<test suite=\"suite\" name=\"TestName\" time=\"0.1\">"
- "<failure message=\"filename.h(4321) : "
- "&quot;&quot;&apos;&apos;&amp;&amp;&lt;&lt;&gt;&gt;\"/>"
- "</test>"
- "</unittest-results>";
-
- CHECK_EQUAL(expected, output.str());
-}
-
-TEST_FIXTURE(XmlTestReporterFixture, OutputIsCachedUntilReportSummaryIsCalled)
-{
- TestDetails const details("", "", "", 0);
-
- reporter.ReportTestStart(details);
- reporter.ReportFailure(details, "message");
- reporter.ReportTestFinish(details, 1.0F);
- CHECK(output.str().empty());
-
- reporter.ReportSummary(1, 1, 1, 1.0f);
- CHECK(!output.str().empty());
-}
-
-TEST_FIXTURE(XmlTestReporterFixture, EmptyReportSummaryFormat)
-{
- reporter.ReportSummary(0, 0, 0, 0.1f);
-
- const char *expected =
-"<?xml version=\"1.0\"?>"
-"<unittest-results tests=\"0\" failedtests=\"0\" failures=\"0\" time=\"0.1\">"
-"</unittest-results>";
-
- CHECK_EQUAL(expected, output.str());
-}
-
-TEST_FIXTURE(XmlTestReporterFixture, SingleSuccessfulTestReportSummaryFormat)
-{
- TestDetails const details("TestName", "DefaultSuite", "", 0);
-
- reporter.ReportTestStart(details);
- reporter.ReportSummary(1, 0, 0, 0.1f);
-
- const char *expected =
-"<?xml version=\"1.0\"?>"
-"<unittest-results tests=\"1\" failedtests=\"0\" failures=\"0\" time=\"0.1\">"
-"<test suite=\"DefaultSuite\" name=\"TestName\" time=\"0\"/>"
-"</unittest-results>";
-
- CHECK_EQUAL(expected, output.str());
-}
-
-TEST_FIXTURE(XmlTestReporterFixture, SingleFailedTestReportSummaryFormat)
-{
- TestDetails const details("A Test", "suite", "A File", 4321);
-
- reporter.ReportTestStart(details);
- reporter.ReportFailure(details, "A Failure");
- reporter.ReportSummary(1, 1, 1, 0.1f);
-
- const char *expected =
- "<?xml version=\"1.0\"?>"
- "<unittest-results tests=\"1\" failedtests=\"1\" failures=\"1\" time=\"0.1\">"
- "<test suite=\"suite\" name=\"A Test\" time=\"0\">"
- "<failure message=\"A File(4321) : A Failure\"/>"
- "</test>"
- "</unittest-results>";
-
- CHECK_EQUAL(expected, output.str());
-}
-
-TEST_FIXTURE(XmlTestReporterFixture, FailureMessageIsXMLEscaped)
-{
- TestDetails const details("TestName", "suite", "filename.h", 4321);
-
- reporter.ReportTestStart(details);
- reporter.ReportFailure(details, "\"\'&<>");
- reporter.ReportTestFinish(details, 0.1f);
- reporter.ReportSummary(1, 1, 1, 0.1f);
-
- char const* expected =
- "<?xml version=\"1.0\"?>"
- "<unittest-results tests=\"1\" failedtests=\"1\" failures=\"1\" time=\"0.1\">"
- "<test suite=\"suite\" name=\"TestName\" time=\"0.1\">"
- "<failure message=\"filename.h(4321) : &quot;&apos;&amp;&lt;&gt;\"/>"
- "</test>"
- "</unittest-results>";
-
- CHECK_EQUAL(expected, output.str());
-}
-
-TEST_FIXTURE(XmlTestReporterFixture, OneFailureAndOneSuccess)
-{
- TestDetails const failedDetails("FailedTest", "suite", "fail.h", 1);
- reporter.ReportTestStart(failedDetails);
- reporter.ReportFailure(failedDetails, "expected 1 but was 2");
- reporter.ReportTestFinish(failedDetails, 0.1f);
-
- TestDetails const succeededDetails("SucceededTest", "suite", "", 0);
- reporter.ReportTestStart(succeededDetails);
- reporter.ReportTestFinish(succeededDetails, 1.0f);
- reporter.ReportSummary(2, 1, 1, 1.1f);
-
- char const* expected =
- "<?xml version=\"1.0\"?>"
- "<unittest-results tests=\"2\" failedtests=\"1\" failures=\"1\" time=\"1.1\">"
- "<test suite=\"suite\" name=\"FailedTest\" time=\"0.1\">"
- "<failure message=\"fail.h(1) : expected 1 but was 2\"/>"
- "</test>"
- "<test suite=\"suite\" name=\"SucceededTest\" time=\"1\"/>"
- "</unittest-results>";
-
- CHECK_EQUAL(expected, output.str());
-}
-
-TEST_FIXTURE(XmlTestReporterFixture, MultipleFailures)
-{
- TestDetails const failedDetails1("FailedTest", "suite", "fail.h", 1);
- TestDetails const failedDetails2("FailedTest", "suite", "fail.h", 31);
-
- reporter.ReportTestStart(failedDetails1);
- reporter.ReportFailure(failedDetails1, "expected 1 but was 2");
- reporter.ReportFailure(failedDetails2, "expected one but was two");
- reporter.ReportTestFinish(failedDetails1, 0.1f);
-
- reporter.ReportSummary(1, 1, 2, 1.1f);
-
- char const* expected =
- "<?xml version=\"1.0\"?>"
- "<unittest-results tests=\"1\" failedtests=\"1\" failures=\"2\" time=\"1.1\">"
- "<test suite=\"suite\" name=\"FailedTest\" time=\"0.1\">"
- "<failure message=\"fail.h(1) : expected 1 but was 2\"/>"
- "<failure message=\"fail.h(31) : expected one but was two\"/>"
- "</test>"
- "</unittest-results>";
-
- CHECK_EQUAL(expected, output.str());
-}
-
-}
diff --git a/3rdparty/bx/3rdparty/catch/catch.hpp b/3rdparty/bx/3rdparty/catch/catch.hpp
new file mode 100644
index 00000000000..7df2fd09c00
--- /dev/null
+++ b/3rdparty/bx/3rdparty/catch/catch.hpp
@@ -0,0 +1,10485 @@
+/*
+ * Catch v1.5.4
+ * Generated: 2016-05-12 19:16:01.957320
+ * ----------------------------------------------------------
+ * This file has been merged from multiple headers. Please don't edit it directly
+ * Copyright (c) 2012 Two Blue Cubes Ltd. All rights reserved.
+ *
+ * Distributed under the Boost Software License, Version 1.0. (See accompanying
+ * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+ */
+#ifndef TWOBLUECUBES_SINGLE_INCLUDE_CATCH_HPP_INCLUDED
+#define TWOBLUECUBES_SINGLE_INCLUDE_CATCH_HPP_INCLUDED
+
+#define TWOBLUECUBES_CATCH_HPP_INCLUDED
+
+#ifdef __clang__
+# pragma clang system_header
+#elif defined __GNUC__
+# pragma GCC system_header
+#endif
+
+// #included from: internal/catch_suppress_warnings.h
+
+#ifdef __clang__
+# ifdef __ICC // icpc defines the __clang__ macro
+# pragma warning(push)
+# pragma warning(disable: 161 1682)
+# else // __ICC
+# pragma clang diagnostic ignored "-Wglobal-constructors"
+# pragma clang diagnostic ignored "-Wvariadic-macros"
+# pragma clang diagnostic ignored "-Wc99-extensions"
+# pragma clang diagnostic ignored "-Wunused-variable"
+# pragma clang diagnostic push
+# pragma clang diagnostic ignored "-Wpadded"
+# pragma clang diagnostic ignored "-Wc++98-compat"
+# pragma clang diagnostic ignored "-Wc++98-compat-pedantic"
+# pragma clang diagnostic ignored "-Wswitch-enum"
+# pragma clang diagnostic ignored "-Wcovered-switch-default"
+# endif
+#elif defined __GNUC__
+# pragma GCC diagnostic ignored "-Wvariadic-macros"
+# pragma GCC diagnostic ignored "-Wunused-variable"
+# pragma GCC diagnostic push
+# pragma GCC diagnostic ignored "-Wpadded"
+#endif
+#if defined(CATCH_CONFIG_MAIN) || defined(CATCH_CONFIG_RUNNER)
+# define CATCH_IMPL
+#endif
+
+#ifdef CATCH_IMPL
+# ifndef CLARA_CONFIG_MAIN
+# define CLARA_CONFIG_MAIN_NOT_DEFINED
+# define CLARA_CONFIG_MAIN
+# endif
+#endif
+
+// #included from: internal/catch_notimplemented_exception.h
+#define TWOBLUECUBES_CATCH_NOTIMPLEMENTED_EXCEPTION_H_INCLUDED
+
+// #included from: catch_common.h
+#define TWOBLUECUBES_CATCH_COMMON_H_INCLUDED
+
+#define INTERNAL_CATCH_UNIQUE_NAME_LINE2( name, line ) name##line
+#define INTERNAL_CATCH_UNIQUE_NAME_LINE( name, line ) INTERNAL_CATCH_UNIQUE_NAME_LINE2( name, line )
+#ifdef CATCH_CONFIG_COUNTER
+# define INTERNAL_CATCH_UNIQUE_NAME( name ) INTERNAL_CATCH_UNIQUE_NAME_LINE( name, __COUNTER__ )
+#else
+# define INTERNAL_CATCH_UNIQUE_NAME( name ) INTERNAL_CATCH_UNIQUE_NAME_LINE( name, __LINE__ )
+#endif
+
+#define INTERNAL_CATCH_STRINGIFY2( expr ) #expr
+#define INTERNAL_CATCH_STRINGIFY( expr ) INTERNAL_CATCH_STRINGIFY2( expr )
+
+#include <sstream>
+#include <stdexcept>
+#include <algorithm>
+
+// #included from: catch_compiler_capabilities.h
+#define TWOBLUECUBES_CATCH_COMPILER_CAPABILITIES_HPP_INCLUDED
+
+// Detect a number of compiler features - mostly C++11/14 conformance - by compiler
+// The following features are defined:
+//
+// CATCH_CONFIG_CPP11_NULLPTR : is nullptr supported?
+// CATCH_CONFIG_CPP11_NOEXCEPT : is noexcept supported?
+// CATCH_CONFIG_CPP11_GENERATED_METHODS : The delete and default keywords for compiler generated methods
+// CATCH_CONFIG_CPP11_IS_ENUM : std::is_enum is supported?
+// CATCH_CONFIG_CPP11_TUPLE : std::tuple is supported
+// CATCH_CONFIG_CPP11_LONG_LONG : is long long supported?
+// CATCH_CONFIG_CPP11_OVERRIDE : is override supported?
+// CATCH_CONFIG_CPP11_UNIQUE_PTR : is unique_ptr supported (otherwise use auto_ptr)
+
+// CATCH_CONFIG_CPP11_OR_GREATER : Is C++11 supported?
+
+// CATCH_CONFIG_VARIADIC_MACROS : are variadic macros supported?
+// CATCH_CONFIG_COUNTER : is the __COUNTER__ macro supported?
+// ****************
+// Note to maintainers: if new toggles are added please document them
+// in configuration.md, too
+// ****************
+
+// In general each macro has a _NO_<feature name> form
+// (e.g. CATCH_CONFIG_CPP11_NO_NULLPTR) which disables the feature.
+// Many features, at point of detection, define an _INTERNAL_ macro, so they
+// can be combined, en-mass, with the _NO_ forms later.
+
+// All the C++11 features can be disabled with CATCH_CONFIG_NO_CPP11
+
+#if defined(__cplusplus) && __cplusplus >= 201103L
+# define CATCH_CPP11_OR_GREATER
+#endif
+
+#ifdef __clang__
+
+# if __has_feature(cxx_nullptr)
+# define CATCH_INTERNAL_CONFIG_CPP11_NULLPTR
+# endif
+
+# if __has_feature(cxx_noexcept)
+# define CATCH_INTERNAL_CONFIG_CPP11_NOEXCEPT
+# endif
+
+# if defined(CATCH_CPP11_OR_GREATER)
+# define CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS _Pragma( "clang diagnostic ignored \"-Wparentheses\"" )
+# endif
+
+#endif // __clang__
+
+////////////////////////////////////////////////////////////////////////////////
+// Borland
+#ifdef __BORLANDC__
+
+#endif // __BORLANDC__
+
+////////////////////////////////////////////////////////////////////////////////
+// EDG
+#ifdef __EDG_VERSION__
+
+#endif // __EDG_VERSION__
+
+////////////////////////////////////////////////////////////////////////////////
+// Digital Mars
+#ifdef __DMC__
+
+#endif // __DMC__
+
+////////////////////////////////////////////////////////////////////////////////
+// GCC
+#ifdef __GNUC__
+
+# if __GNUC__ == 4 && __GNUC_MINOR__ >= 6 && defined(__GXX_EXPERIMENTAL_CXX0X__)
+# define CATCH_INTERNAL_CONFIG_CPP11_NULLPTR
+# endif
+
+# if !defined(CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS) && defined(CATCH_CPP11_OR_GREATER)
+# define CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS _Pragma( "GCC diagnostic ignored \"-Wparentheses\"" )
+# endif
+
+// - otherwise more recent versions define __cplusplus >= 201103L
+// and will get picked up below
+
+#endif // __GNUC__
+
+////////////////////////////////////////////////////////////////////////////////
+// Visual C++
+#ifdef _MSC_VER
+
+#if (_MSC_VER >= 1600)
+# define CATCH_INTERNAL_CONFIG_CPP11_NULLPTR
+# define CATCH_INTERNAL_CONFIG_CPP11_UNIQUE_PTR
+#endif
+
+#if (_MSC_VER >= 1900 ) // (VC++ 13 (VS2015))
+#define CATCH_INTERNAL_CONFIG_CPP11_NOEXCEPT
+#define CATCH_INTERNAL_CONFIG_CPP11_GENERATED_METHODS
+#endif
+
+#endif // _MSC_VER
+
+////////////////////////////////////////////////////////////////////////////////
+
+// Use variadic macros if the compiler supports them
+#if ( defined _MSC_VER && _MSC_VER > 1400 && !defined __EDGE__) || \
+ ( defined __WAVE__ && __WAVE_HAS_VARIADICS ) || \
+ ( defined __GNUC__ && __GNUC__ >= 3 ) || \
+ ( !defined __cplusplus && __STDC_VERSION__ >= 199901L || __cplusplus >= 201103L )
+
+#define CATCH_INTERNAL_CONFIG_VARIADIC_MACROS
+
+#endif
+
+// Use __COUNTER__ if the compiler supports it
+#if ( defined _MSC_VER && _MSC_VER >= 1300 ) || \
+ ( defined __GNUC__ && __GNUC__ >= 4 && __GNUC_MINOR__ >= 3 ) || \
+ ( defined __clang__ && __clang_major__ >= 3 )
+
+#define CATCH_INTERNAL_CONFIG_COUNTER
+
+#endif
+
+////////////////////////////////////////////////////////////////////////////////
+// C++ language feature support
+
+// catch all support for C++11
+#if defined(CATCH_CPP11_OR_GREATER)
+
+# if !defined(CATCH_INTERNAL_CONFIG_CPP11_NULLPTR)
+# define CATCH_INTERNAL_CONFIG_CPP11_NULLPTR
+# endif
+
+# ifndef CATCH_INTERNAL_CONFIG_CPP11_NOEXCEPT
+# define CATCH_INTERNAL_CONFIG_CPP11_NOEXCEPT
+# endif
+
+# ifndef CATCH_INTERNAL_CONFIG_CPP11_GENERATED_METHODS
+# define CATCH_INTERNAL_CONFIG_CPP11_GENERATED_METHODS
+# endif
+
+# ifndef CATCH_INTERNAL_CONFIG_CPP11_IS_ENUM
+# define CATCH_INTERNAL_CONFIG_CPP11_IS_ENUM
+# endif
+
+# ifndef CATCH_INTERNAL_CONFIG_CPP11_TUPLE
+# define CATCH_INTERNAL_CONFIG_CPP11_TUPLE
+# endif
+
+# ifndef CATCH_INTERNAL_CONFIG_VARIADIC_MACROS
+# define CATCH_INTERNAL_CONFIG_VARIADIC_MACROS
+# endif
+
+# if !defined(CATCH_INTERNAL_CONFIG_CPP11_LONG_LONG)
+# define CATCH_INTERNAL_CONFIG_CPP11_LONG_LONG
+# endif
+
+# if !defined(CATCH_INTERNAL_CONFIG_CPP11_OVERRIDE)
+# define CATCH_INTERNAL_CONFIG_CPP11_OVERRIDE
+# endif
+# if !defined(CATCH_INTERNAL_CONFIG_CPP11_UNIQUE_PTR)
+# define CATCH_INTERNAL_CONFIG_CPP11_UNIQUE_PTR
+# endif
+
+#endif // __cplusplus >= 201103L
+
+// Now set the actual defines based on the above + anything the user has configured
+#if defined(CATCH_INTERNAL_CONFIG_CPP11_NULLPTR) && !defined(CATCH_CONFIG_CPP11_NO_NULLPTR) && !defined(CATCH_CONFIG_CPP11_NULLPTR) && !defined(CATCH_CONFIG_NO_CPP11)
+# define CATCH_CONFIG_CPP11_NULLPTR
+#endif
+#if defined(CATCH_INTERNAL_CONFIG_CPP11_NOEXCEPT) && !defined(CATCH_CONFIG_CPP11_NO_NOEXCEPT) && !defined(CATCH_CONFIG_CPP11_NOEXCEPT) && !defined(CATCH_CONFIG_NO_CPP11)
+# define CATCH_CONFIG_CPP11_NOEXCEPT
+#endif
+#if defined(CATCH_INTERNAL_CONFIG_CPP11_GENERATED_METHODS) && !defined(CATCH_CONFIG_CPP11_NO_GENERATED_METHODS) && !defined(CATCH_CONFIG_CPP11_GENERATED_METHODS) && !defined(CATCH_CONFIG_NO_CPP11)
+# define CATCH_CONFIG_CPP11_GENERATED_METHODS
+#endif
+#if defined(CATCH_INTERNAL_CONFIG_CPP11_IS_ENUM) && !defined(CATCH_CONFIG_CPP11_NO_IS_ENUM) && !defined(CATCH_CONFIG_CPP11_IS_ENUM) && !defined(CATCH_CONFIG_NO_CPP11)
+# define CATCH_CONFIG_CPP11_IS_ENUM
+#endif
+#if defined(CATCH_INTERNAL_CONFIG_CPP11_TUPLE) && !defined(CATCH_CONFIG_CPP11_NO_TUPLE) && !defined(CATCH_CONFIG_CPP11_TUPLE) && !defined(CATCH_CONFIG_NO_CPP11)
+# define CATCH_CONFIG_CPP11_TUPLE
+#endif
+#if defined(CATCH_INTERNAL_CONFIG_VARIADIC_MACROS) && !defined(CATCH_CONFIG_NO_VARIADIC_MACROS) && !defined(CATCH_CONFIG_VARIADIC_MACROS)
+# define CATCH_CONFIG_VARIADIC_MACROS
+#endif
+#if defined(CATCH_INTERNAL_CONFIG_CPP11_LONG_LONG) && !defined(CATCH_CONFIG_NO_LONG_LONG) && !defined(CATCH_CONFIG_CPP11_LONG_LONG) && !defined(CATCH_CONFIG_NO_CPP11)
+# define CATCH_CONFIG_CPP11_LONG_LONG
+#endif
+#if defined(CATCH_INTERNAL_CONFIG_CPP11_OVERRIDE) && !defined(CATCH_CONFIG_NO_OVERRIDE) && !defined(CATCH_CONFIG_CPP11_OVERRIDE) && !defined(CATCH_CONFIG_NO_CPP11)
+# define CATCH_CONFIG_CPP11_OVERRIDE
+#endif
+#if defined(CATCH_INTERNAL_CONFIG_CPP11_UNIQUE_PTR) && !defined(CATCH_CONFIG_NO_UNIQUE_PTR) && !defined(CATCH_CONFIG_CPP11_UNIQUE_PTR) && !defined(CATCH_CONFIG_NO_CPP11)
+# define CATCH_CONFIG_CPP11_UNIQUE_PTR
+#endif
+#if defined(CATCH_INTERNAL_CONFIG_COUNTER) && !defined(CATCH_CONFIG_NO_COUNTER) && !defined(CATCH_CONFIG_COUNTER)
+# define CATCH_CONFIG_COUNTER
+#endif
+
+#if !defined(CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS)
+# define CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS
+#endif
+
+// noexcept support:
+#if defined(CATCH_CONFIG_CPP11_NOEXCEPT) && !defined(CATCH_NOEXCEPT)
+# define CATCH_NOEXCEPT noexcept
+# define CATCH_NOEXCEPT_IS(x) noexcept(x)
+#else
+# define CATCH_NOEXCEPT throw()
+# define CATCH_NOEXCEPT_IS(x)
+#endif
+
+// nullptr support
+#ifdef CATCH_CONFIG_CPP11_NULLPTR
+# define CATCH_NULL nullptr
+#else
+# define CATCH_NULL NULL
+#endif
+
+// override support
+#ifdef CATCH_CONFIG_CPP11_OVERRIDE
+# define CATCH_OVERRIDE override
+#else
+# define CATCH_OVERRIDE
+#endif
+
+// unique_ptr support
+#ifdef CATCH_CONFIG_CPP11_UNIQUE_PTR
+# define CATCH_AUTO_PTR( T ) std::unique_ptr<T>
+#else
+# define CATCH_AUTO_PTR( T ) std::auto_ptr<T>
+#endif
+
+namespace Catch {
+
+ struct IConfig;
+
+ struct CaseSensitive { enum Choice {
+ Yes,
+ No
+ }; };
+
+ class NonCopyable {
+#ifdef CATCH_CONFIG_CPP11_GENERATED_METHODS
+ NonCopyable( NonCopyable const& ) = delete;
+ NonCopyable( NonCopyable && ) = delete;
+ NonCopyable& operator = ( NonCopyable const& ) = delete;
+ NonCopyable& operator = ( NonCopyable && ) = delete;
+#else
+ NonCopyable( NonCopyable const& info );
+ NonCopyable& operator = ( NonCopyable const& );
+#endif
+
+ protected:
+ NonCopyable() {}
+ virtual ~NonCopyable();
+ };
+
+ class SafeBool {
+ public:
+ typedef void (SafeBool::*type)() const;
+
+ static type makeSafe( bool value ) {
+ return value ? &SafeBool::trueValue : 0;
+ }
+ private:
+ void trueValue() const {}
+ };
+
+ template<typename ContainerT>
+ inline void deleteAll( ContainerT& container ) {
+ typename ContainerT::const_iterator it = container.begin();
+ typename ContainerT::const_iterator itEnd = container.end();
+ for(; it != itEnd; ++it )
+ delete *it;
+ }
+ template<typename AssociativeContainerT>
+ inline void deleteAllValues( AssociativeContainerT& container ) {
+ typename AssociativeContainerT::const_iterator it = container.begin();
+ typename AssociativeContainerT::const_iterator itEnd = container.end();
+ for(; it != itEnd; ++it )
+ delete it->second;
+ }
+
+ bool startsWith( std::string const& s, std::string const& prefix );
+ bool endsWith( std::string const& s, std::string const& suffix );
+ bool contains( std::string const& s, std::string const& infix );
+ void toLowerInPlace( std::string& s );
+ std::string toLower( std::string const& s );
+ std::string trim( std::string const& str );
+ bool replaceInPlace( std::string& str, std::string const& replaceThis, std::string const& withThis );
+
+ struct pluralise {
+ pluralise( std::size_t count, std::string const& label );
+
+ friend std::ostream& operator << ( std::ostream& os, pluralise const& pluraliser );
+
+ std::size_t m_count;
+ std::string m_label;
+ };
+
+ struct SourceLineInfo {
+
+ SourceLineInfo();
+ SourceLineInfo( char const* _file, std::size_t _line );
+ SourceLineInfo( SourceLineInfo const& other );
+# ifdef CATCH_CONFIG_CPP11_GENERATED_METHODS
+ SourceLineInfo( SourceLineInfo && ) = default;
+ SourceLineInfo& operator = ( SourceLineInfo const& ) = default;
+ SourceLineInfo& operator = ( SourceLineInfo && ) = default;
+# endif
+ bool empty() const;
+ bool operator == ( SourceLineInfo const& other ) const;
+ bool operator < ( SourceLineInfo const& other ) const;
+
+ std::string file;
+ std::size_t line;
+ };
+
+ std::ostream& operator << ( std::ostream& os, SourceLineInfo const& info );
+
+ // This is just here to avoid compiler warnings with macro constants and boolean literals
+ inline bool isTrue( bool value ){ return value; }
+ inline bool alwaysTrue() { return true; }
+ inline bool alwaysFalse() { return false; }
+
+ void throwLogicError( std::string const& message, SourceLineInfo const& locationInfo );
+
+ void seedRng( IConfig const& config );
+ unsigned int rngSeed();
+
+ // Use this in variadic streaming macros to allow
+ // >> +StreamEndStop
+ // as well as
+ // >> stuff +StreamEndStop
+ struct StreamEndStop {
+ std::string operator+() {
+ return std::string();
+ }
+ };
+ template<typename T>
+ T const& operator + ( T const& value, StreamEndStop ) {
+ return value;
+ }
+}
+
+#define CATCH_INTERNAL_LINEINFO ::Catch::SourceLineInfo( __FILE__, static_cast<std::size_t>( __LINE__ ) )
+#define CATCH_INTERNAL_ERROR( msg ) ::Catch::throwLogicError( msg, CATCH_INTERNAL_LINEINFO );
+
+#include <ostream>
+
+namespace Catch {
+
+ class NotImplementedException : public std::exception
+ {
+ public:
+ NotImplementedException( SourceLineInfo const& lineInfo );
+ NotImplementedException( NotImplementedException const& ) {}
+
+ virtual ~NotImplementedException() CATCH_NOEXCEPT {}
+
+ virtual const char* what() const CATCH_NOEXCEPT;
+
+ private:
+ std::string m_what;
+ SourceLineInfo m_lineInfo;
+ };
+
+} // end namespace Catch
+
+///////////////////////////////////////////////////////////////////////////////
+#define CATCH_NOT_IMPLEMENTED throw Catch::NotImplementedException( CATCH_INTERNAL_LINEINFO )
+
+// #included from: internal/catch_context.h
+#define TWOBLUECUBES_CATCH_CONTEXT_H_INCLUDED
+
+// #included from: catch_interfaces_generators.h
+#define TWOBLUECUBES_CATCH_INTERFACES_GENERATORS_H_INCLUDED
+
+#include <string>
+
+namespace Catch {
+
+ struct IGeneratorInfo {
+ virtual ~IGeneratorInfo();
+ virtual bool moveNext() = 0;
+ virtual std::size_t getCurrentIndex() const = 0;
+ };
+
+ struct IGeneratorsForTest {
+ virtual ~IGeneratorsForTest();
+
+ virtual IGeneratorInfo& getGeneratorInfo( std::string const& fileInfo, std::size_t size ) = 0;
+ virtual bool moveNext() = 0;
+ };
+
+ IGeneratorsForTest* createGeneratorsForTest();
+
+} // end namespace Catch
+
+// #included from: catch_ptr.hpp
+#define TWOBLUECUBES_CATCH_PTR_HPP_INCLUDED
+
+#ifdef __clang__
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wpadded"
+#endif
+
+namespace Catch {
+
+ // An intrusive reference counting smart pointer.
+ // T must implement addRef() and release() methods
+ // typically implementing the IShared interface
+ template<typename T>
+ class Ptr {
+ public:
+ Ptr() : m_p( CATCH_NULL ){}
+ Ptr( T* p ) : m_p( p ){
+ if( m_p )
+ m_p->addRef();
+ }
+ Ptr( Ptr const& other ) : m_p( other.m_p ){
+ if( m_p )
+ m_p->addRef();
+ }
+ ~Ptr(){
+ if( m_p )
+ m_p->release();
+ }
+ void reset() {
+ if( m_p )
+ m_p->release();
+ m_p = CATCH_NULL;
+ }
+ Ptr& operator = ( T* p ){
+ Ptr temp( p );
+ swap( temp );
+ return *this;
+ }
+ Ptr& operator = ( Ptr const& other ){
+ Ptr temp( other );
+ swap( temp );
+ return *this;
+ }
+ void swap( Ptr& other ) { std::swap( m_p, other.m_p ); }
+ T* get() const{ return m_p; }
+ T& operator*() const { return *m_p; }
+ T* operator->() const { return m_p; }
+ bool operator !() const { return m_p == CATCH_NULL; }
+ operator SafeBool::type() const { return SafeBool::makeSafe( m_p != CATCH_NULL ); }
+
+ private:
+ T* m_p;
+ };
+
+ struct IShared : NonCopyable {
+ virtual ~IShared();
+ virtual void addRef() const = 0;
+ virtual void release() const = 0;
+ };
+
+ template<typename T = IShared>
+ struct SharedImpl : T {
+
+ SharedImpl() : m_rc( 0 ){}
+
+ virtual void addRef() const {
+ ++m_rc;
+ }
+ virtual void release() const {
+ if( --m_rc == 0 )
+ delete this;
+ }
+
+ mutable unsigned int m_rc;
+ };
+
+} // end namespace Catch
+
+#ifdef __clang__
+#pragma clang diagnostic pop
+#endif
+
+#include <memory>
+#include <vector>
+#include <stdlib.h>
+
+namespace Catch {
+
+ class TestCase;
+ class Stream;
+ struct IResultCapture;
+ struct IRunner;
+ struct IGeneratorsForTest;
+ struct IConfig;
+
+ struct IContext
+ {
+ virtual ~IContext();
+
+ virtual IResultCapture* getResultCapture() = 0;
+ virtual IRunner* getRunner() = 0;
+ virtual size_t getGeneratorIndex( std::string const& fileInfo, size_t totalSize ) = 0;
+ virtual bool advanceGeneratorsForCurrentTest() = 0;
+ virtual Ptr<IConfig const> getConfig() const = 0;
+ };
+
+ struct IMutableContext : IContext
+ {
+ virtual ~IMutableContext();
+ virtual void setResultCapture( IResultCapture* resultCapture ) = 0;
+ virtual void setRunner( IRunner* runner ) = 0;
+ virtual void setConfig( Ptr<IConfig const> const& config ) = 0;
+ };
+
+ IContext& getCurrentContext();
+ IMutableContext& getCurrentMutableContext();
+ void cleanUpContext();
+ Stream createStream( std::string const& streamName );
+
+}
+
+// #included from: internal/catch_test_registry.hpp
+#define TWOBLUECUBES_CATCH_TEST_REGISTRY_HPP_INCLUDED
+
+// #included from: catch_interfaces_testcase.h
+#define TWOBLUECUBES_CATCH_INTERFACES_TESTCASE_H_INCLUDED
+
+#include <vector>
+
+namespace Catch {
+
+ class TestSpec;
+
+ struct ITestCase : IShared {
+ virtual void invoke () const = 0;
+ protected:
+ virtual ~ITestCase();
+ };
+
+ class TestCase;
+ struct IConfig;
+
+ struct ITestCaseRegistry {
+ virtual ~ITestCaseRegistry();
+ virtual std::vector<TestCase> const& getAllTests() const = 0;
+ virtual std::vector<TestCase> const& getAllTestsSorted( IConfig const& config ) const = 0;
+ };
+
+ bool matchTest( TestCase const& testCase, TestSpec const& testSpec, IConfig const& config );
+ std::vector<TestCase> filterTests( std::vector<TestCase> const& testCases, TestSpec const& testSpec, IConfig const& config );
+ std::vector<TestCase> const& getAllTestCasesSorted( IConfig const& config );
+
+}
+
+namespace Catch {
+
+template<typename C>
+class MethodTestCase : public SharedImpl<ITestCase> {
+
+public:
+ MethodTestCase( void (C::*method)() ) : m_method( method ) {}
+
+ virtual void invoke() const {
+ C obj;
+ (obj.*m_method)();
+ }
+
+private:
+ virtual ~MethodTestCase() {}
+
+ void (C::*m_method)();
+};
+
+typedef void(*TestFunction)();
+
+struct NameAndDesc {
+ NameAndDesc( const char* _name = "", const char* _description= "" )
+ : name( _name ), description( _description )
+ {}
+
+ const char* name;
+ const char* description;
+};
+
+void registerTestCase
+ ( ITestCase* testCase,
+ char const* className,
+ NameAndDesc const& nameAndDesc,
+ SourceLineInfo const& lineInfo );
+
+struct AutoReg {
+
+ AutoReg
+ ( TestFunction function,
+ SourceLineInfo const& lineInfo,
+ NameAndDesc const& nameAndDesc );
+
+ template<typename C>
+ AutoReg
+ ( void (C::*method)(),
+ char const* className,
+ NameAndDesc const& nameAndDesc,
+ SourceLineInfo const& lineInfo ) {
+
+ registerTestCase
+ ( new MethodTestCase<C>( method ),
+ className,
+ nameAndDesc,
+ lineInfo );
+ }
+
+ ~AutoReg();
+
+private:
+ AutoReg( AutoReg const& );
+ void operator= ( AutoReg const& );
+};
+
+void registerTestCaseFunction
+ ( TestFunction function,
+ SourceLineInfo const& lineInfo,
+ NameAndDesc const& nameAndDesc );
+
+} // end namespace Catch
+
+#ifdef CATCH_CONFIG_VARIADIC_MACROS
+ ///////////////////////////////////////////////////////////////////////////////
+ #define INTERNAL_CATCH_TESTCASE2( TestName, ... ) \
+ static void TestName(); \
+ namespace{ Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( &TestName, CATCH_INTERNAL_LINEINFO, Catch::NameAndDesc( __VA_ARGS__ ) ); }\
+ static void TestName()
+ #define INTERNAL_CATCH_TESTCASE( ... ) \
+ INTERNAL_CATCH_TESTCASE2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ), __VA_ARGS__ )
+
+ ///////////////////////////////////////////////////////////////////////////////
+ #define INTERNAL_CATCH_METHOD_AS_TEST_CASE( QualifiedMethod, ... ) \
+ namespace{ Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( &QualifiedMethod, "&" #QualifiedMethod, Catch::NameAndDesc( __VA_ARGS__ ), CATCH_INTERNAL_LINEINFO ); }
+
+ ///////////////////////////////////////////////////////////////////////////////
+ #define INTERNAL_CATCH_TEST_CASE_METHOD2( TestName, ClassName, ... )\
+ namespace{ \
+ struct TestName : ClassName{ \
+ void test(); \
+ }; \
+ Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar ) ( &TestName::test, #ClassName, Catch::NameAndDesc( __VA_ARGS__ ), CATCH_INTERNAL_LINEINFO ); \
+ } \
+ void TestName::test()
+ #define INTERNAL_CATCH_TEST_CASE_METHOD( ClassName, ... ) \
+ INTERNAL_CATCH_TEST_CASE_METHOD2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ), ClassName, __VA_ARGS__ )
+
+ ///////////////////////////////////////////////////////////////////////////////
+ #define INTERNAL_CATCH_REGISTER_TESTCASE( Function, ... ) \
+ Catch::AutoReg( Function, CATCH_INTERNAL_LINEINFO, Catch::NameAndDesc( __VA_ARGS__ ) );
+
+#else
+ ///////////////////////////////////////////////////////////////////////////////
+ #define INTERNAL_CATCH_TESTCASE2( TestName, Name, Desc ) \
+ static void TestName(); \
+ namespace{ Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( &TestName, CATCH_INTERNAL_LINEINFO, Catch::NameAndDesc( Name, Desc ) ); }\
+ static void TestName()
+ #define INTERNAL_CATCH_TESTCASE( Name, Desc ) \
+ INTERNAL_CATCH_TESTCASE2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ), Name, Desc )
+
+ ///////////////////////////////////////////////////////////////////////////////
+ #define INTERNAL_CATCH_METHOD_AS_TEST_CASE( QualifiedMethod, Name, Desc ) \
+ namespace{ Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( &QualifiedMethod, "&" #QualifiedMethod, Catch::NameAndDesc( Name, Desc ), CATCH_INTERNAL_LINEINFO ); }
+
+ ///////////////////////////////////////////////////////////////////////////////
+ #define INTERNAL_CATCH_TEST_CASE_METHOD2( TestCaseName, ClassName, TestName, Desc )\
+ namespace{ \
+ struct TestCaseName : ClassName{ \
+ void test(); \
+ }; \
+ Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar ) ( &TestCaseName::test, #ClassName, Catch::NameAndDesc( TestName, Desc ), CATCH_INTERNAL_LINEINFO ); \
+ } \
+ void TestCaseName::test()
+ #define INTERNAL_CATCH_TEST_CASE_METHOD( ClassName, TestName, Desc )\
+ INTERNAL_CATCH_TEST_CASE_METHOD2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ), ClassName, TestName, Desc )
+
+ ///////////////////////////////////////////////////////////////////////////////
+ #define INTERNAL_CATCH_REGISTER_TESTCASE( Function, Name, Desc ) \
+ Catch::AutoReg( Function, CATCH_INTERNAL_LINEINFO, Catch::NameAndDesc( Name, Desc ) );
+#endif
+
+// #included from: internal/catch_capture.hpp
+#define TWOBLUECUBES_CATCH_CAPTURE_HPP_INCLUDED
+
+// #included from: catch_result_builder.h
+#define TWOBLUECUBES_CATCH_RESULT_BUILDER_H_INCLUDED
+
+// #included from: catch_result_type.h
+#define TWOBLUECUBES_CATCH_RESULT_TYPE_H_INCLUDED
+
+namespace Catch {
+
+ // ResultWas::OfType enum
+ struct ResultWas { enum OfType {
+ Unknown = -1,
+ Ok = 0,
+ Info = 1,
+ Warning = 2,
+
+ FailureBit = 0x10,
+
+ ExpressionFailed = FailureBit | 1,
+ ExplicitFailure = FailureBit | 2,
+
+ Exception = 0x100 | FailureBit,
+
+ ThrewException = Exception | 1,
+ DidntThrowException = Exception | 2,
+
+ FatalErrorCondition = 0x200 | FailureBit
+
+ }; };
+
+ inline bool isOk( ResultWas::OfType resultType ) {
+ return ( resultType & ResultWas::FailureBit ) == 0;
+ }
+ inline bool isJustInfo( int flags ) {
+ return flags == ResultWas::Info;
+ }
+
+ // ResultDisposition::Flags enum
+ struct ResultDisposition { enum Flags {
+ Normal = 0x01,
+
+ ContinueOnFailure = 0x02, // Failures fail test, but execution continues
+ FalseTest = 0x04, // Prefix expression with !
+ SuppressFail = 0x08 // Failures are reported but do not fail the test
+ }; };
+
+ inline ResultDisposition::Flags operator | ( ResultDisposition::Flags lhs, ResultDisposition::Flags rhs ) {
+ return static_cast<ResultDisposition::Flags>( static_cast<int>( lhs ) | static_cast<int>( rhs ) );
+ }
+
+ inline bool shouldContinueOnFailure( int flags ) { return ( flags & ResultDisposition::ContinueOnFailure ) != 0; }
+ inline bool isFalseTest( int flags ) { return ( flags & ResultDisposition::FalseTest ) != 0; }
+ inline bool shouldSuppressFailure( int flags ) { return ( flags & ResultDisposition::SuppressFail ) != 0; }
+
+} // end namespace Catch
+
+// #included from: catch_assertionresult.h
+#define TWOBLUECUBES_CATCH_ASSERTIONRESULT_H_INCLUDED
+
+#include <string>
+
+namespace Catch {
+
+ struct AssertionInfo
+ {
+ AssertionInfo() {}
+ AssertionInfo( std::string const& _macroName,
+ SourceLineInfo const& _lineInfo,
+ std::string const& _capturedExpression,
+ ResultDisposition::Flags _resultDisposition );
+
+ std::string macroName;
+ SourceLineInfo lineInfo;
+ std::string capturedExpression;
+ ResultDisposition::Flags resultDisposition;
+ };
+
+ struct AssertionResultData
+ {
+ AssertionResultData() : resultType( ResultWas::Unknown ) {}
+
+ std::string reconstructedExpression;
+ std::string message;
+ ResultWas::OfType resultType;
+ };
+
+ class AssertionResult {
+ public:
+ AssertionResult();
+ AssertionResult( AssertionInfo const& info, AssertionResultData const& data );
+ ~AssertionResult();
+# ifdef CATCH_CONFIG_CPP11_GENERATED_METHODS
+ AssertionResult( AssertionResult const& ) = default;
+ AssertionResult( AssertionResult && ) = default;
+ AssertionResult& operator = ( AssertionResult const& ) = default;
+ AssertionResult& operator = ( AssertionResult && ) = default;
+# endif
+
+ bool isOk() const;
+ bool succeeded() const;
+ ResultWas::OfType getResultType() const;
+ bool hasExpression() const;
+ bool hasMessage() const;
+ std::string getExpression() const;
+ std::string getExpressionInMacro() const;
+ bool hasExpandedExpression() const;
+ std::string getExpandedExpression() const;
+ std::string getMessage() const;
+ SourceLineInfo getSourceInfo() const;
+ std::string getTestMacroName() const;
+
+ protected:
+ AssertionInfo m_info;
+ AssertionResultData m_resultData;
+ };
+
+} // end namespace Catch
+
+// #included from: catch_matchers.hpp
+#define TWOBLUECUBES_CATCH_MATCHERS_HPP_INCLUDED
+
+namespace Catch {
+namespace Matchers {
+ namespace Impl {
+
+ namespace Generic {
+ template<typename ExpressionT> class AllOf;
+ template<typename ExpressionT> class AnyOf;
+ template<typename ExpressionT> class Not;
+ }
+
+ template<typename ExpressionT>
+ struct Matcher : SharedImpl<IShared>
+ {
+ typedef ExpressionT ExpressionType;
+
+ virtual ~Matcher() {}
+ virtual Ptr<Matcher> clone() const = 0;
+ virtual bool match( ExpressionT const& expr ) const = 0;
+ virtual std::string toString() const = 0;
+
+ Generic::AllOf<ExpressionT> operator && ( Matcher<ExpressionT> const& other ) const;
+ Generic::AnyOf<ExpressionT> operator || ( Matcher<ExpressionT> const& other ) const;
+ Generic::Not<ExpressionT> operator ! () const;
+ };
+
+ template<typename DerivedT, typename ExpressionT>
+ struct MatcherImpl : Matcher<ExpressionT> {
+
+ virtual Ptr<Matcher<ExpressionT> > clone() const {
+ return Ptr<Matcher<ExpressionT> >( new DerivedT( static_cast<DerivedT const&>( *this ) ) );
+ }
+ };
+
+ namespace Generic {
+ template<typename ExpressionT>
+ class Not : public MatcherImpl<Not<ExpressionT>, ExpressionT> {
+ public:
+ explicit Not( Matcher<ExpressionT> const& matcher ) : m_matcher(matcher.clone()) {}
+ Not( Not const& other ) : m_matcher( other.m_matcher ) {}
+
+ virtual bool match( ExpressionT const& expr ) const CATCH_OVERRIDE {
+ return !m_matcher->match( expr );
+ }
+
+ virtual std::string toString() const CATCH_OVERRIDE {
+ return "not " + m_matcher->toString();
+ }
+ private:
+ Ptr< Matcher<ExpressionT> > m_matcher;
+ };
+
+ template<typename ExpressionT>
+ class AllOf : public MatcherImpl<AllOf<ExpressionT>, ExpressionT> {
+ public:
+
+ AllOf() {}
+ AllOf( AllOf const& other ) : m_matchers( other.m_matchers ) {}
+
+ AllOf& add( Matcher<ExpressionT> const& matcher ) {
+ m_matchers.push_back( matcher.clone() );
+ return *this;
+ }
+ virtual bool match( ExpressionT const& expr ) const
+ {
+ for( std::size_t i = 0; i < m_matchers.size(); ++i )
+ if( !m_matchers[i]->match( expr ) )
+ return false;
+ return true;
+ }
+ virtual std::string toString() const {
+ std::ostringstream oss;
+ oss << "( ";
+ for( std::size_t i = 0; i < m_matchers.size(); ++i ) {
+ if( i != 0 )
+ oss << " and ";
+ oss << m_matchers[i]->toString();
+ }
+ oss << " )";
+ return oss.str();
+ }
+
+ AllOf operator && ( Matcher<ExpressionT> const& other ) const {
+ AllOf allOfExpr( *this );
+ allOfExpr.add( other );
+ return allOfExpr;
+ }
+
+ private:
+ std::vector<Ptr<Matcher<ExpressionT> > > m_matchers;
+ };
+
+ template<typename ExpressionT>
+ class AnyOf : public MatcherImpl<AnyOf<ExpressionT>, ExpressionT> {
+ public:
+
+ AnyOf() {}
+ AnyOf( AnyOf const& other ) : m_matchers( other.m_matchers ) {}
+
+ AnyOf& add( Matcher<ExpressionT> const& matcher ) {
+ m_matchers.push_back( matcher.clone() );
+ return *this;
+ }
+ virtual bool match( ExpressionT const& expr ) const
+ {
+ for( std::size_t i = 0; i < m_matchers.size(); ++i )
+ if( m_matchers[i]->match( expr ) )
+ return true;
+ return false;
+ }
+ virtual std::string toString() const {
+ std::ostringstream oss;
+ oss << "( ";
+ for( std::size_t i = 0; i < m_matchers.size(); ++i ) {
+ if( i != 0 )
+ oss << " or ";
+ oss << m_matchers[i]->toString();
+ }
+ oss << " )";
+ return oss.str();
+ }
+
+ AnyOf operator || ( Matcher<ExpressionT> const& other ) const {
+ AnyOf anyOfExpr( *this );
+ anyOfExpr.add( other );
+ return anyOfExpr;
+ }
+
+ private:
+ std::vector<Ptr<Matcher<ExpressionT> > > m_matchers;
+ };
+
+ } // namespace Generic
+
+ template<typename ExpressionT>
+ Generic::AllOf<ExpressionT> Matcher<ExpressionT>::operator && ( Matcher<ExpressionT> const& other ) const {
+ Generic::AllOf<ExpressionT> allOfExpr;
+ allOfExpr.add( *this );
+ allOfExpr.add( other );
+ return allOfExpr;
+ }
+
+ template<typename ExpressionT>
+ Generic::AnyOf<ExpressionT> Matcher<ExpressionT>::operator || ( Matcher<ExpressionT> const& other ) const {
+ Generic::AnyOf<ExpressionT> anyOfExpr;
+ anyOfExpr.add( *this );
+ anyOfExpr.add( other );
+ return anyOfExpr;
+ }
+
+ template<typename ExpressionT>
+ Generic::Not<ExpressionT> Matcher<ExpressionT>::operator ! () const {
+ return Generic::Not<ExpressionT>( *this );
+ }
+
+ namespace StdString {
+
+ inline std::string makeString( std::string const& str ) { return str; }
+ inline std::string makeString( const char* str ) { return str ? std::string( str ) : std::string(); }
+
+ struct CasedString
+ {
+ CasedString( std::string const& str, CaseSensitive::Choice caseSensitivity )
+ : m_caseSensitivity( caseSensitivity ),
+ m_str( adjustString( str ) )
+ {}
+ std::string adjustString( std::string const& str ) const {
+ return m_caseSensitivity == CaseSensitive::No
+ ? toLower( str )
+ : str;
+
+ }
+ std::string toStringSuffix() const
+ {
+ return m_caseSensitivity == CaseSensitive::No
+ ? " (case insensitive)"
+ : "";
+ }
+ CaseSensitive::Choice m_caseSensitivity;
+ std::string m_str;
+ };
+
+ struct Equals : MatcherImpl<Equals, std::string> {
+ Equals( std::string const& str, CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes )
+ : m_data( str, caseSensitivity )
+ {}
+ Equals( Equals const& other ) : m_data( other.m_data ){}
+
+ virtual ~Equals();
+
+ virtual bool match( std::string const& expr ) const {
+ return m_data.m_str == m_data.adjustString( expr );;
+ }
+ virtual std::string toString() const {
+ return "equals: \"" + m_data.m_str + "\"" + m_data.toStringSuffix();
+ }
+
+ CasedString m_data;
+ };
+
+ struct Contains : MatcherImpl<Contains, std::string> {
+ Contains( std::string const& substr, CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes )
+ : m_data( substr, caseSensitivity ){}
+ Contains( Contains const& other ) : m_data( other.m_data ){}
+
+ virtual ~Contains();
+
+ virtual bool match( std::string const& expr ) const {
+ return m_data.adjustString( expr ).find( m_data.m_str ) != std::string::npos;
+ }
+ virtual std::string toString() const {
+ return "contains: \"" + m_data.m_str + "\"" + m_data.toStringSuffix();
+ }
+
+ CasedString m_data;
+ };
+
+ struct StartsWith : MatcherImpl<StartsWith, std::string> {
+ StartsWith( std::string const& substr, CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes )
+ : m_data( substr, caseSensitivity ){}
+
+ StartsWith( StartsWith const& other ) : m_data( other.m_data ){}
+
+ virtual ~StartsWith();
+
+ virtual bool match( std::string const& expr ) const {
+ return startsWith( m_data.adjustString( expr ), m_data.m_str );
+ }
+ virtual std::string toString() const {
+ return "starts with: \"" + m_data.m_str + "\"" + m_data.toStringSuffix();
+ }
+
+ CasedString m_data;
+ };
+
+ struct EndsWith : MatcherImpl<EndsWith, std::string> {
+ EndsWith( std::string const& substr, CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes )
+ : m_data( substr, caseSensitivity ){}
+ EndsWith( EndsWith const& other ) : m_data( other.m_data ){}
+
+ virtual ~EndsWith();
+
+ virtual bool match( std::string const& expr ) const {
+ return endsWith( m_data.adjustString( expr ), m_data.m_str );
+ }
+ virtual std::string toString() const {
+ return "ends with: \"" + m_data.m_str + "\"" + m_data.toStringSuffix();
+ }
+
+ CasedString m_data;
+ };
+ } // namespace StdString
+ } // namespace Impl
+
+ // The following functions create the actual matcher objects.
+ // This allows the types to be inferred
+ template<typename ExpressionT>
+ inline Impl::Generic::Not<ExpressionT> Not( Impl::Matcher<ExpressionT> const& m ) {
+ return Impl::Generic::Not<ExpressionT>( m );
+ }
+
+ template<typename ExpressionT>
+ inline Impl::Generic::AllOf<ExpressionT> AllOf( Impl::Matcher<ExpressionT> const& m1,
+ Impl::Matcher<ExpressionT> const& m2 ) {
+ return Impl::Generic::AllOf<ExpressionT>().add( m1 ).add( m2 );
+ }
+ template<typename ExpressionT>
+ inline Impl::Generic::AllOf<ExpressionT> AllOf( Impl::Matcher<ExpressionT> const& m1,
+ Impl::Matcher<ExpressionT> const& m2,
+ Impl::Matcher<ExpressionT> const& m3 ) {
+ return Impl::Generic::AllOf<ExpressionT>().add( m1 ).add( m2 ).add( m3 );
+ }
+ template<typename ExpressionT>
+ inline Impl::Generic::AnyOf<ExpressionT> AnyOf( Impl::Matcher<ExpressionT> const& m1,
+ Impl::Matcher<ExpressionT> const& m2 ) {
+ return Impl::Generic::AnyOf<ExpressionT>().add( m1 ).add( m2 );
+ }
+ template<typename ExpressionT>
+ inline Impl::Generic::AnyOf<ExpressionT> AnyOf( Impl::Matcher<ExpressionT> const& m1,
+ Impl::Matcher<ExpressionT> const& m2,
+ Impl::Matcher<ExpressionT> const& m3 ) {
+ return Impl::Generic::AnyOf<ExpressionT>().add( m1 ).add( m2 ).add( m3 );
+ }
+
+ inline Impl::StdString::Equals Equals( std::string const& str, CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes ) {
+ return Impl::StdString::Equals( str, caseSensitivity );
+ }
+ inline Impl::StdString::Equals Equals( const char* str, CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes ) {
+ return Impl::StdString::Equals( Impl::StdString::makeString( str ), caseSensitivity );
+ }
+ inline Impl::StdString::Contains Contains( std::string const& substr, CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes ) {
+ return Impl::StdString::Contains( substr, caseSensitivity );
+ }
+ inline Impl::StdString::Contains Contains( const char* substr, CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes ) {
+ return Impl::StdString::Contains( Impl::StdString::makeString( substr ), caseSensitivity );
+ }
+ inline Impl::StdString::StartsWith StartsWith( std::string const& substr ) {
+ return Impl::StdString::StartsWith( substr );
+ }
+ inline Impl::StdString::StartsWith StartsWith( const char* substr ) {
+ return Impl::StdString::StartsWith( Impl::StdString::makeString( substr ) );
+ }
+ inline Impl::StdString::EndsWith EndsWith( std::string const& substr ) {
+ return Impl::StdString::EndsWith( substr );
+ }
+ inline Impl::StdString::EndsWith EndsWith( const char* substr ) {
+ return Impl::StdString::EndsWith( Impl::StdString::makeString( substr ) );
+ }
+
+} // namespace Matchers
+
+using namespace Matchers;
+
+} // namespace Catch
+
+namespace Catch {
+
+ struct TestFailureException{};
+
+ template<typename T> class ExpressionLhs;
+
+ struct STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison;
+
+ struct CopyableStream {
+ CopyableStream() {}
+ CopyableStream( CopyableStream const& other ) {
+ oss << other.oss.str();
+ }
+ CopyableStream& operator=( CopyableStream const& other ) {
+ oss.str("");
+ oss << other.oss.str();
+ return *this;
+ }
+ std::ostringstream oss;
+ };
+
+ class ResultBuilder {
+ public:
+ ResultBuilder( char const* macroName,
+ SourceLineInfo const& lineInfo,
+ char const* capturedExpression,
+ ResultDisposition::Flags resultDisposition,
+ char const* secondArg = "" );
+
+ template<typename T>
+ ExpressionLhs<T const&> operator <= ( T const& operand );
+ ExpressionLhs<bool> operator <= ( bool value );
+
+ template<typename T>
+ ResultBuilder& operator << ( T const& value ) {
+ m_stream.oss << value;
+ return *this;
+ }
+
+ template<typename RhsT> STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator && ( RhsT const& );
+ template<typename RhsT> STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator || ( RhsT const& );
+
+ ResultBuilder& setResultType( ResultWas::OfType result );
+ ResultBuilder& setResultType( bool result );
+ ResultBuilder& setLhs( std::string const& lhs );
+ ResultBuilder& setRhs( std::string const& rhs );
+ ResultBuilder& setOp( std::string const& op );
+
+ void endExpression();
+
+ std::string reconstructExpression() const;
+ AssertionResult build() const;
+
+ void useActiveException( ResultDisposition::Flags resultDisposition = ResultDisposition::Normal );
+ void captureResult( ResultWas::OfType resultType );
+ void captureExpression();
+ void captureExpectedException( std::string const& expectedMessage );
+ void captureExpectedException( Matchers::Impl::Matcher<std::string> const& matcher );
+ void handleResult( AssertionResult const& result );
+ void react();
+ bool shouldDebugBreak() const;
+ bool allowThrows() const;
+
+ private:
+ AssertionInfo m_assertionInfo;
+ AssertionResultData m_data;
+ struct ExprComponents {
+ ExprComponents() : testFalse( false ) {}
+ bool testFalse;
+ std::string lhs, rhs, op;
+ } m_exprComponents;
+ CopyableStream m_stream;
+
+ bool m_shouldDebugBreak;
+ bool m_shouldThrow;
+ };
+
+} // namespace Catch
+
+// Include after due to circular dependency:
+// #included from: catch_expression_lhs.hpp
+#define TWOBLUECUBES_CATCH_EXPRESSION_LHS_HPP_INCLUDED
+
+// #included from: catch_evaluate.hpp
+#define TWOBLUECUBES_CATCH_EVALUATE_HPP_INCLUDED
+
+#ifdef _MSC_VER
+#pragma warning(push)
+#pragma warning(disable:4389) // '==' : signed/unsigned mismatch
+#endif
+
+#include <cstddef>
+
+namespace Catch {
+namespace Internal {
+
+ enum Operator {
+ IsEqualTo,
+ IsNotEqualTo,
+ IsLessThan,
+ IsGreaterThan,
+ IsLessThanOrEqualTo,
+ IsGreaterThanOrEqualTo
+ };
+
+ template<Operator Op> struct OperatorTraits { static const char* getName(){ return "*error*"; } };
+ template<> struct OperatorTraits<IsEqualTo> { static const char* getName(){ return "=="; } };
+ template<> struct OperatorTraits<IsNotEqualTo> { static const char* getName(){ return "!="; } };
+ template<> struct OperatorTraits<IsLessThan> { static const char* getName(){ return "<"; } };
+ template<> struct OperatorTraits<IsGreaterThan> { static const char* getName(){ return ">"; } };
+ template<> struct OperatorTraits<IsLessThanOrEqualTo> { static const char* getName(){ return "<="; } };
+ template<> struct OperatorTraits<IsGreaterThanOrEqualTo>{ static const char* getName(){ return ">="; } };
+
+ template<typename T>
+ inline T& opCast(T const& t) { return const_cast<T&>(t); }
+
+// nullptr_t support based on pull request #154 from Konstantin Baumann
+#ifdef CATCH_CONFIG_CPP11_NULLPTR
+ inline std::nullptr_t opCast(std::nullptr_t) { return nullptr; }
+#endif // CATCH_CONFIG_CPP11_NULLPTR
+
+ // So the compare overloads can be operator agnostic we convey the operator as a template
+ // enum, which is used to specialise an Evaluator for doing the comparison.
+ template<typename T1, typename T2, Operator Op>
+ class Evaluator{};
+
+ template<typename T1, typename T2>
+ struct Evaluator<T1, T2, IsEqualTo> {
+ static bool evaluate( T1 const& lhs, T2 const& rhs) {
+ return bool( opCast( lhs ) == opCast( rhs ) );
+ }
+ };
+ template<typename T1, typename T2>
+ struct Evaluator<T1, T2, IsNotEqualTo> {
+ static bool evaluate( T1 const& lhs, T2 const& rhs ) {
+ return bool( opCast( lhs ) != opCast( rhs ) );
+ }
+ };
+ template<typename T1, typename T2>
+ struct Evaluator<T1, T2, IsLessThan> {
+ static bool evaluate( T1 const& lhs, T2 const& rhs ) {
+ return bool( opCast( lhs ) < opCast( rhs ) );
+ }
+ };
+ template<typename T1, typename T2>
+ struct Evaluator<T1, T2, IsGreaterThan> {
+ static bool evaluate( T1 const& lhs, T2 const& rhs ) {
+ return bool( opCast( lhs ) > opCast( rhs ) );
+ }
+ };
+ template<typename T1, typename T2>
+ struct Evaluator<T1, T2, IsGreaterThanOrEqualTo> {
+ static bool evaluate( T1 const& lhs, T2 const& rhs ) {
+ return bool( opCast( lhs ) >= opCast( rhs ) );
+ }
+ };
+ template<typename T1, typename T2>
+ struct Evaluator<T1, T2, IsLessThanOrEqualTo> {
+ static bool evaluate( T1 const& lhs, T2 const& rhs ) {
+ return bool( opCast( lhs ) <= opCast( rhs ) );
+ }
+ };
+
+ template<Operator Op, typename T1, typename T2>
+ bool applyEvaluator( T1 const& lhs, T2 const& rhs ) {
+ return Evaluator<T1, T2, Op>::evaluate( lhs, rhs );
+ }
+
+ // This level of indirection allows us to specialise for integer types
+ // to avoid signed/ unsigned warnings
+
+ // "base" overload
+ template<Operator Op, typename T1, typename T2>
+ bool compare( T1 const& lhs, T2 const& rhs ) {
+ return Evaluator<T1, T2, Op>::evaluate( lhs, rhs );
+ }
+
+ // unsigned X to int
+ template<Operator Op> bool compare( unsigned int lhs, int rhs ) {
+ return applyEvaluator<Op>( lhs, static_cast<unsigned int>( rhs ) );
+ }
+ template<Operator Op> bool compare( unsigned long lhs, int rhs ) {
+ return applyEvaluator<Op>( lhs, static_cast<unsigned int>( rhs ) );
+ }
+ template<Operator Op> bool compare( unsigned char lhs, int rhs ) {
+ return applyEvaluator<Op>( lhs, static_cast<unsigned int>( rhs ) );
+ }
+
+ // unsigned X to long
+ template<Operator Op> bool compare( unsigned int lhs, long rhs ) {
+ return applyEvaluator<Op>( lhs, static_cast<unsigned long>( rhs ) );
+ }
+ template<Operator Op> bool compare( unsigned long lhs, long rhs ) {
+ return applyEvaluator<Op>( lhs, static_cast<unsigned long>( rhs ) );
+ }
+ template<Operator Op> bool compare( unsigned char lhs, long rhs ) {
+ return applyEvaluator<Op>( lhs, static_cast<unsigned long>( rhs ) );
+ }
+
+ // int to unsigned X
+ template<Operator Op> bool compare( int lhs, unsigned int rhs ) {
+ return applyEvaluator<Op>( static_cast<unsigned int>( lhs ), rhs );
+ }
+ template<Operator Op> bool compare( int lhs, unsigned long rhs ) {
+ return applyEvaluator<Op>( static_cast<unsigned int>( lhs ), rhs );
+ }
+ template<Operator Op> bool compare( int lhs, unsigned char rhs ) {
+ return applyEvaluator<Op>( static_cast<unsigned int>( lhs ), rhs );
+ }
+
+ // long to unsigned X
+ template<Operator Op> bool compare( long lhs, unsigned int rhs ) {
+ return applyEvaluator<Op>( static_cast<unsigned long>( lhs ), rhs );
+ }
+ template<Operator Op> bool compare( long lhs, unsigned long rhs ) {
+ return applyEvaluator<Op>( static_cast<unsigned long>( lhs ), rhs );
+ }
+ template<Operator Op> bool compare( long lhs, unsigned char rhs ) {
+ return applyEvaluator<Op>( static_cast<unsigned long>( lhs ), rhs );
+ }
+
+ // pointer to long (when comparing against NULL)
+ template<Operator Op, typename T> bool compare( long lhs, T* rhs ) {
+ return Evaluator<T*, T*, Op>::evaluate( reinterpret_cast<T*>( lhs ), rhs );
+ }
+ template<Operator Op, typename T> bool compare( T* lhs, long rhs ) {
+ return Evaluator<T*, T*, Op>::evaluate( lhs, reinterpret_cast<T*>( rhs ) );
+ }
+
+ // pointer to int (when comparing against NULL)
+ template<Operator Op, typename T> bool compare( int lhs, T* rhs ) {
+ return Evaluator<T*, T*, Op>::evaluate( reinterpret_cast<T*>( lhs ), rhs );
+ }
+ template<Operator Op, typename T> bool compare( T* lhs, int rhs ) {
+ return Evaluator<T*, T*, Op>::evaluate( lhs, reinterpret_cast<T*>( rhs ) );
+ }
+
+#ifdef CATCH_CONFIG_CPP11_LONG_LONG
+ // long long to unsigned X
+ template<Operator Op> bool compare( long long lhs, unsigned int rhs ) {
+ return applyEvaluator<Op>( static_cast<unsigned long>( lhs ), rhs );
+ }
+ template<Operator Op> bool compare( long long lhs, unsigned long rhs ) {
+ return applyEvaluator<Op>( static_cast<unsigned long>( lhs ), rhs );
+ }
+ template<Operator Op> bool compare( long long lhs, unsigned long long rhs ) {
+ return applyEvaluator<Op>( static_cast<unsigned long>( lhs ), rhs );
+ }
+ template<Operator Op> bool compare( long long lhs, unsigned char rhs ) {
+ return applyEvaluator<Op>( static_cast<unsigned long>( lhs ), rhs );
+ }
+
+ // unsigned long long to X
+ template<Operator Op> bool compare( unsigned long long lhs, int rhs ) {
+ return applyEvaluator<Op>( static_cast<long>( lhs ), rhs );
+ }
+ template<Operator Op> bool compare( unsigned long long lhs, long rhs ) {
+ return applyEvaluator<Op>( static_cast<long>( lhs ), rhs );
+ }
+ template<Operator Op> bool compare( unsigned long long lhs, long long rhs ) {
+ return applyEvaluator<Op>( static_cast<long>( lhs ), rhs );
+ }
+ template<Operator Op> bool compare( unsigned long long lhs, char rhs ) {
+ return applyEvaluator<Op>( static_cast<long>( lhs ), rhs );
+ }
+
+ // pointer to long long (when comparing against NULL)
+ template<Operator Op, typename T> bool compare( long long lhs, T* rhs ) {
+ return Evaluator<T*, T*, Op>::evaluate( reinterpret_cast<T*>( lhs ), rhs );
+ }
+ template<Operator Op, typename T> bool compare( T* lhs, long long rhs ) {
+ return Evaluator<T*, T*, Op>::evaluate( lhs, reinterpret_cast<T*>( rhs ) );
+ }
+#endif // CATCH_CONFIG_CPP11_LONG_LONG
+
+#ifdef CATCH_CONFIG_CPP11_NULLPTR
+ // pointer to nullptr_t (when comparing against nullptr)
+ template<Operator Op, typename T> bool compare( std::nullptr_t, T* rhs ) {
+ return Evaluator<T*, T*, Op>::evaluate( nullptr, rhs );
+ }
+ template<Operator Op, typename T> bool compare( T* lhs, std::nullptr_t ) {
+ return Evaluator<T*, T*, Op>::evaluate( lhs, nullptr );
+ }
+#endif // CATCH_CONFIG_CPP11_NULLPTR
+
+} // end of namespace Internal
+} // end of namespace Catch
+
+#ifdef _MSC_VER
+#pragma warning(pop)
+#endif
+
+// #included from: catch_tostring.h
+#define TWOBLUECUBES_CATCH_TOSTRING_H_INCLUDED
+
+#include <sstream>
+#include <iomanip>
+#include <limits>
+#include <vector>
+#include <cstddef>
+
+#ifdef __OBJC__
+// #included from: catch_objc_arc.hpp
+#define TWOBLUECUBES_CATCH_OBJC_ARC_HPP_INCLUDED
+
+#import <Foundation/Foundation.h>
+
+#ifdef __has_feature
+#define CATCH_ARC_ENABLED __has_feature(objc_arc)
+#else
+#define CATCH_ARC_ENABLED 0
+#endif
+
+void arcSafeRelease( NSObject* obj );
+id performOptionalSelector( id obj, SEL sel );
+
+#if !CATCH_ARC_ENABLED
+inline void arcSafeRelease( NSObject* obj ) {
+ [obj release];
+}
+inline id performOptionalSelector( id obj, SEL sel ) {
+ if( [obj respondsToSelector: sel] )
+ return [obj performSelector: sel];
+ return nil;
+}
+#define CATCH_UNSAFE_UNRETAINED
+#define CATCH_ARC_STRONG
+#else
+inline void arcSafeRelease( NSObject* ){}
+inline id performOptionalSelector( id obj, SEL sel ) {
+#ifdef __clang__
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Warc-performSelector-leaks"
+#endif
+ if( [obj respondsToSelector: sel] )
+ return [obj performSelector: sel];
+#ifdef __clang__
+#pragma clang diagnostic pop
+#endif
+ return nil;
+}
+#define CATCH_UNSAFE_UNRETAINED __unsafe_unretained
+#define CATCH_ARC_STRONG __strong
+#endif
+
+#endif
+
+#ifdef CATCH_CONFIG_CPP11_TUPLE
+#include <tuple>
+#endif
+
+#ifdef CATCH_CONFIG_CPP11_IS_ENUM
+#include <type_traits>
+#endif
+
+namespace Catch {
+
+// Why we're here.
+template<typename T>
+std::string toString( T const& value );
+
+// Built in overloads
+
+std::string toString( std::string const& value );
+std::string toString( std::wstring const& value );
+std::string toString( const char* const value );
+std::string toString( char* const value );
+std::string toString( const wchar_t* const value );
+std::string toString( wchar_t* const value );
+std::string toString( int value );
+std::string toString( unsigned long value );
+std::string toString( unsigned int value );
+std::string toString( const double value );
+std::string toString( const float value );
+std::string toString( bool value );
+std::string toString( char value );
+std::string toString( signed char value );
+std::string toString( unsigned char value );
+
+#ifdef CATCH_CONFIG_CPP11_LONG_LONG
+std::string toString( long long value );
+std::string toString( unsigned long long value );
+#endif
+
+#ifdef CATCH_CONFIG_CPP11_NULLPTR
+std::string toString( std::nullptr_t );
+#endif
+
+#ifdef __OBJC__
+ std::string toString( NSString const * const& nsstring );
+ std::string toString( NSString * CATCH_ARC_STRONG const& nsstring );
+ std::string toString( NSObject* const& nsObject );
+#endif
+
+namespace Detail {
+
+ extern const std::string unprintableString;
+
+ struct BorgType {
+ template<typename T> BorgType( T const& );
+ };
+
+ struct TrueType { char sizer[1]; };
+ struct FalseType { char sizer[2]; };
+
+ TrueType& testStreamable( std::ostream& );
+ FalseType testStreamable( FalseType );
+
+ FalseType operator<<( std::ostream const&, BorgType const& );
+
+ template<typename T>
+ struct IsStreamInsertable {
+ static std::ostream &s;
+ static T const&t;
+ enum { value = sizeof( testStreamable(s << t) ) == sizeof( TrueType ) };
+ };
+
+#if defined(CATCH_CONFIG_CPP11_IS_ENUM)
+ template<typename T,
+ bool IsEnum = std::is_enum<T>::value
+ >
+ struct EnumStringMaker
+ {
+ static std::string convert( T const& ) { return unprintableString; }
+ };
+
+ template<typename T>
+ struct EnumStringMaker<T,true>
+ {
+ static std::string convert( T const& v )
+ {
+ return ::Catch::toString(
+ static_cast<typename std::underlying_type<T>::type>(v)
+ );
+ }
+ };
+#endif
+ template<bool C>
+ struct StringMakerBase {
+#if defined(CATCH_CONFIG_CPP11_IS_ENUM)
+ template<typename T>
+ static std::string convert( T const& v )
+ {
+ return EnumStringMaker<T>::convert( v );
+ }
+#else
+ template<typename T>
+ static std::string convert( T const& ) { return unprintableString; }
+#endif
+ };
+
+ template<>
+ struct StringMakerBase<true> {
+ template<typename T>
+ static std::string convert( T const& _value ) {
+ std::ostringstream oss;
+ oss << _value;
+ return oss.str();
+ }
+ };
+
+ std::string rawMemoryToString( const void *object, std::size_t size );
+
+ template<typename T>
+ inline std::string rawMemoryToString( const T& object ) {
+ return rawMemoryToString( &object, sizeof(object) );
+ }
+
+} // end namespace Detail
+
+template<typename T>
+struct StringMaker :
+ Detail::StringMakerBase<Detail::IsStreamInsertable<T>::value> {};
+
+template<typename T>
+struct StringMaker<T*> {
+ template<typename U>
+ static std::string convert( U* p ) {
+ if( !p )
+ return "NULL";
+ else
+ return Detail::rawMemoryToString( p );
+ }
+};
+
+template<typename R, typename C>
+struct StringMaker<R C::*> {
+ static std::string convert( R C::* p ) {
+ if( !p )
+ return "NULL";
+ else
+ return Detail::rawMemoryToString( p );
+ }
+};
+
+namespace Detail {
+ template<typename InputIterator>
+ std::string rangeToString( InputIterator first, InputIterator last );
+}
+
+//template<typename T, typename Allocator>
+//struct StringMaker<std::vector<T, Allocator> > {
+// static std::string convert( std::vector<T,Allocator> const& v ) {
+// return Detail::rangeToString( v.begin(), v.end() );
+// }
+//};
+
+template<typename T, typename Allocator>
+std::string toString( std::vector<T,Allocator> const& v ) {
+ return Detail::rangeToString( v.begin(), v.end() );
+}
+
+#ifdef CATCH_CONFIG_CPP11_TUPLE
+
+// toString for tuples
+namespace TupleDetail {
+ template<
+ typename Tuple,
+ std::size_t N = 0,
+ bool = (N < std::tuple_size<Tuple>::value)
+ >
+ struct ElementPrinter {
+ static void print( const Tuple& tuple, std::ostream& os )
+ {
+ os << ( N ? ", " : " " )
+ << Catch::toString(std::get<N>(tuple));
+ ElementPrinter<Tuple,N+1>::print(tuple,os);
+ }
+ };
+
+ template<
+ typename Tuple,
+ std::size_t N
+ >
+ struct ElementPrinter<Tuple,N,false> {
+ static void print( const Tuple&, std::ostream& ) {}
+ };
+
+}
+
+template<typename ...Types>
+struct StringMaker<std::tuple<Types...>> {
+
+ static std::string convert( const std::tuple<Types...>& tuple )
+ {
+ std::ostringstream os;
+ os << '{';
+ TupleDetail::ElementPrinter<std::tuple<Types...>>::print( tuple, os );
+ os << " }";
+ return os.str();
+ }
+};
+#endif // CATCH_CONFIG_CPP11_TUPLE
+
+namespace Detail {
+ template<typename T>
+ std::string makeString( T const& value ) {
+ return StringMaker<T>::convert( value );
+ }
+} // end namespace Detail
+
+/// \brief converts any type to a string
+///
+/// The default template forwards on to ostringstream - except when an
+/// ostringstream overload does not exist - in which case it attempts to detect
+/// that and writes {?}.
+/// Overload (not specialise) this template for custom typs that you don't want
+/// to provide an ostream overload for.
+template<typename T>
+std::string toString( T const& value ) {
+ return StringMaker<T>::convert( value );
+}
+
+ namespace Detail {
+ template<typename InputIterator>
+ std::string rangeToString( InputIterator first, InputIterator last ) {
+ std::ostringstream oss;
+ oss << "{ ";
+ if( first != last ) {
+ oss << Catch::toString( *first );
+ for( ++first ; first != last ; ++first )
+ oss << ", " << Catch::toString( *first );
+ }
+ oss << " }";
+ return oss.str();
+ }
+}
+
+} // end namespace Catch
+
+namespace Catch {
+
+// Wraps the LHS of an expression and captures the operator and RHS (if any) -
+// wrapping them all in a ResultBuilder object
+template<typename T>
+class ExpressionLhs {
+ ExpressionLhs& operator = ( ExpressionLhs const& );
+# ifdef CATCH_CONFIG_CPP11_GENERATED_METHODS
+ ExpressionLhs& operator = ( ExpressionLhs && ) = delete;
+# endif
+
+public:
+ ExpressionLhs( ResultBuilder& rb, T lhs ) : m_rb( rb ), m_lhs( lhs ) {}
+# ifdef CATCH_CONFIG_CPP11_GENERATED_METHODS
+ ExpressionLhs( ExpressionLhs const& ) = default;
+ ExpressionLhs( ExpressionLhs && ) = default;
+# endif
+
+ template<typename RhsT>
+ ResultBuilder& operator == ( RhsT const& rhs ) {
+ return captureExpression<Internal::IsEqualTo>( rhs );
+ }
+
+ template<typename RhsT>
+ ResultBuilder& operator != ( RhsT const& rhs ) {
+ return captureExpression<Internal::IsNotEqualTo>( rhs );
+ }
+
+ template<typename RhsT>
+ ResultBuilder& operator < ( RhsT const& rhs ) {
+ return captureExpression<Internal::IsLessThan>( rhs );
+ }
+
+ template<typename RhsT>
+ ResultBuilder& operator > ( RhsT const& rhs ) {
+ return captureExpression<Internal::IsGreaterThan>( rhs );
+ }
+
+ template<typename RhsT>
+ ResultBuilder& operator <= ( RhsT const& rhs ) {
+ return captureExpression<Internal::IsLessThanOrEqualTo>( rhs );
+ }
+
+ template<typename RhsT>
+ ResultBuilder& operator >= ( RhsT const& rhs ) {
+ return captureExpression<Internal::IsGreaterThanOrEqualTo>( rhs );
+ }
+
+ ResultBuilder& operator == ( bool rhs ) {
+ return captureExpression<Internal::IsEqualTo>( rhs );
+ }
+
+ ResultBuilder& operator != ( bool rhs ) {
+ return captureExpression<Internal::IsNotEqualTo>( rhs );
+ }
+
+ void endExpression() {
+ bool value = m_lhs ? true : false;
+ m_rb
+ .setLhs( Catch::toString( value ) )
+ .setResultType( value )
+ .endExpression();
+ }
+
+ // Only simple binary expressions are allowed on the LHS.
+ // If more complex compositions are required then place the sub expression in parentheses
+ template<typename RhsT> STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator + ( RhsT const& );
+ template<typename RhsT> STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator - ( RhsT const& );
+ template<typename RhsT> STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator / ( RhsT const& );
+ template<typename RhsT> STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator * ( RhsT const& );
+ template<typename RhsT> STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator && ( RhsT const& );
+ template<typename RhsT> STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator || ( RhsT const& );
+
+private:
+ template<Internal::Operator Op, typename RhsT>
+ ResultBuilder& captureExpression( RhsT const& rhs ) {
+ return m_rb
+ .setResultType( Internal::compare<Op>( m_lhs, rhs ) )
+ .setLhs( Catch::toString( m_lhs ) )
+ .setRhs( Catch::toString( rhs ) )
+ .setOp( Internal::OperatorTraits<Op>::getName() );
+ }
+
+private:
+ ResultBuilder& m_rb;
+ T m_lhs;
+};
+
+} // end namespace Catch
+
+
+namespace Catch {
+
+ template<typename T>
+ inline ExpressionLhs<T const&> ResultBuilder::operator <= ( T const& operand ) {
+ return ExpressionLhs<T const&>( *this, operand );
+ }
+
+ inline ExpressionLhs<bool> ResultBuilder::operator <= ( bool value ) {
+ return ExpressionLhs<bool>( *this, value );
+ }
+
+} // namespace Catch
+
+// #included from: catch_message.h
+#define TWOBLUECUBES_CATCH_MESSAGE_H_INCLUDED
+
+#include <string>
+
+namespace Catch {
+
+ struct MessageInfo {
+ MessageInfo( std::string const& _macroName,
+ SourceLineInfo const& _lineInfo,
+ ResultWas::OfType _type );
+
+ std::string macroName;
+ SourceLineInfo lineInfo;
+ ResultWas::OfType type;
+ std::string message;
+ unsigned int sequence;
+
+ bool operator == ( MessageInfo const& other ) const {
+ return sequence == other.sequence;
+ }
+ bool operator < ( MessageInfo const& other ) const {
+ return sequence < other.sequence;
+ }
+ private:
+ static unsigned int globalCount;
+ };
+
+ struct MessageBuilder {
+ MessageBuilder( std::string const& macroName,
+ SourceLineInfo const& lineInfo,
+ ResultWas::OfType type )
+ : m_info( macroName, lineInfo, type )
+ {}
+
+ template<typename T>
+ MessageBuilder& operator << ( T const& value ) {
+ m_stream << value;
+ return *this;
+ }
+
+ MessageInfo m_info;
+ std::ostringstream m_stream;
+ };
+
+ class ScopedMessage {
+ public:
+ ScopedMessage( MessageBuilder const& builder );
+ ScopedMessage( ScopedMessage const& other );
+ ~ScopedMessage();
+
+ MessageInfo m_info;
+ };
+
+} // end namespace Catch
+
+// #included from: catch_interfaces_capture.h
+#define TWOBLUECUBES_CATCH_INTERFACES_CAPTURE_H_INCLUDED
+
+#include <string>
+
+namespace Catch {
+
+ class TestCase;
+ class AssertionResult;
+ struct AssertionInfo;
+ struct SectionInfo;
+ struct SectionEndInfo;
+ struct MessageInfo;
+ class ScopedMessageBuilder;
+ struct Counts;
+
+ struct IResultCapture {
+
+ virtual ~IResultCapture();
+
+ virtual void assertionEnded( AssertionResult const& result ) = 0;
+ virtual bool sectionStarted( SectionInfo const& sectionInfo,
+ Counts& assertions ) = 0;
+ virtual void sectionEnded( SectionEndInfo const& endInfo ) = 0;
+ virtual void sectionEndedEarly( SectionEndInfo const& endInfo ) = 0;
+ virtual void pushScopedMessage( MessageInfo const& message ) = 0;
+ virtual void popScopedMessage( MessageInfo const& message ) = 0;
+
+ virtual std::string getCurrentTestName() const = 0;
+ virtual const AssertionResult* getLastResult() const = 0;
+
+ virtual void handleFatalErrorCondition( std::string const& message ) = 0;
+ };
+
+ IResultCapture& getResultCapture();
+}
+
+// #included from: catch_debugger.h
+#define TWOBLUECUBES_CATCH_DEBUGGER_H_INCLUDED
+
+// #included from: catch_platform.h
+#define TWOBLUECUBES_CATCH_PLATFORM_H_INCLUDED
+
+#if defined(__MAC_OS_X_VERSION_MIN_REQUIRED)
+#define CATCH_PLATFORM_MAC
+#elif defined(__IPHONE_OS_VERSION_MIN_REQUIRED)
+#define CATCH_PLATFORM_IPHONE
+#elif defined(WIN32) || defined(__WIN32__) || defined(_WIN32) || defined(_MSC_VER)
+#define CATCH_PLATFORM_WINDOWS
+#endif
+
+#include <string>
+
+namespace Catch{
+
+ bool isDebuggerActive();
+ void writeToDebugConsole( std::string const& text );
+}
+
+#ifdef CATCH_PLATFORM_MAC
+
+ // The following code snippet based on:
+ // http://cocoawithlove.com/2008/03/break-into-debugger.html
+ #ifdef DEBUG
+ #if defined(__ppc64__) || defined(__ppc__)
+ #define CATCH_BREAK_INTO_DEBUGGER() \
+ if( Catch::isDebuggerActive() ) { \
+ __asm__("li r0, 20\nsc\nnop\nli r0, 37\nli r4, 2\nsc\nnop\n" \
+ : : : "memory","r0","r3","r4" ); \
+ }
+ #else
+ #define CATCH_BREAK_INTO_DEBUGGER() if( Catch::isDebuggerActive() ) {__asm__("int $3\n" : : );}
+ #endif
+ #endif
+
+#elif defined(_MSC_VER)
+ #define CATCH_BREAK_INTO_DEBUGGER() if( Catch::isDebuggerActive() ) { __debugbreak(); }
+#elif defined(__MINGW32__)
+ extern "C" __declspec(dllimport) void __stdcall DebugBreak();
+ #define CATCH_BREAK_INTO_DEBUGGER() if( Catch::isDebuggerActive() ) { DebugBreak(); }
+#endif
+
+#ifndef CATCH_BREAK_INTO_DEBUGGER
+#define CATCH_BREAK_INTO_DEBUGGER() Catch::alwaysTrue();
+#endif
+
+// #included from: catch_interfaces_runner.h
+#define TWOBLUECUBES_CATCH_INTERFACES_RUNNER_H_INCLUDED
+
+namespace Catch {
+ class TestCase;
+
+ struct IRunner {
+ virtual ~IRunner();
+ virtual bool aborting() const = 0;
+ };
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// In the event of a failure works out if the debugger needs to be invoked
+// and/or an exception thrown and takes appropriate action.
+// This needs to be done as a macro so the debugger will stop in the user
+// source code rather than in Catch library code
+#define INTERNAL_CATCH_REACT( resultBuilder ) \
+ if( resultBuilder.shouldDebugBreak() ) CATCH_BREAK_INTO_DEBUGGER(); \
+ resultBuilder.react();
+
+///////////////////////////////////////////////////////////////////////////////
+#define INTERNAL_CATCH_TEST( expr, resultDisposition, macroName ) \
+ do { \
+ Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, #expr, resultDisposition ); \
+ try { \
+ CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS \
+ ( __catchResult <= expr ).endExpression(); \
+ } \
+ catch( ... ) { \
+ __catchResult.useActiveException( Catch::ResultDisposition::Normal ); \
+ } \
+ INTERNAL_CATCH_REACT( __catchResult ) \
+ } while( Catch::isTrue( false && !!(expr) ) ) // expr here is never evaluated at runtime but it forces the compiler to give it a look
+
+///////////////////////////////////////////////////////////////////////////////
+#define INTERNAL_CATCH_IF( expr, resultDisposition, macroName ) \
+ INTERNAL_CATCH_TEST( expr, resultDisposition, macroName ); \
+ if( Catch::getResultCapture().getLastResult()->succeeded() )
+
+///////////////////////////////////////////////////////////////////////////////
+#define INTERNAL_CATCH_ELSE( expr, resultDisposition, macroName ) \
+ INTERNAL_CATCH_TEST( expr, resultDisposition, macroName ); \
+ if( !Catch::getResultCapture().getLastResult()->succeeded() )
+
+///////////////////////////////////////////////////////////////////////////////
+#define INTERNAL_CATCH_NO_THROW( expr, resultDisposition, macroName ) \
+ do { \
+ Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, #expr, resultDisposition ); \
+ try { \
+ expr; \
+ __catchResult.captureResult( Catch::ResultWas::Ok ); \
+ } \
+ catch( ... ) { \
+ __catchResult.useActiveException( resultDisposition ); \
+ } \
+ INTERNAL_CATCH_REACT( __catchResult ) \
+ } while( Catch::alwaysFalse() )
+
+///////////////////////////////////////////////////////////////////////////////
+#define INTERNAL_CATCH_THROWS( expr, resultDisposition, matcher, macroName ) \
+ do { \
+ Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, #expr, resultDisposition, #matcher ); \
+ if( __catchResult.allowThrows() ) \
+ try { \
+ expr; \
+ __catchResult.captureResult( Catch::ResultWas::DidntThrowException ); \
+ } \
+ catch( ... ) { \
+ __catchResult.captureExpectedException( matcher ); \
+ } \
+ else \
+ __catchResult.captureResult( Catch::ResultWas::Ok ); \
+ INTERNAL_CATCH_REACT( __catchResult ) \
+ } while( Catch::alwaysFalse() )
+
+///////////////////////////////////////////////////////////////////////////////
+#define INTERNAL_CATCH_THROWS_AS( expr, exceptionType, resultDisposition, macroName ) \
+ do { \
+ Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, #expr, resultDisposition ); \
+ if( __catchResult.allowThrows() ) \
+ try { \
+ expr; \
+ __catchResult.captureResult( Catch::ResultWas::DidntThrowException ); \
+ } \
+ catch( exceptionType ) { \
+ __catchResult.captureResult( Catch::ResultWas::Ok ); \
+ } \
+ catch( ... ) { \
+ __catchResult.useActiveException( resultDisposition ); \
+ } \
+ else \
+ __catchResult.captureResult( Catch::ResultWas::Ok ); \
+ INTERNAL_CATCH_REACT( __catchResult ) \
+ } while( Catch::alwaysFalse() )
+
+///////////////////////////////////////////////////////////////////////////////
+#ifdef CATCH_CONFIG_VARIADIC_MACROS
+ #define INTERNAL_CATCH_MSG( messageType, resultDisposition, macroName, ... ) \
+ do { \
+ Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, "", resultDisposition ); \
+ __catchResult << __VA_ARGS__ + ::Catch::StreamEndStop(); \
+ __catchResult.captureResult( messageType ); \
+ INTERNAL_CATCH_REACT( __catchResult ) \
+ } while( Catch::alwaysFalse() )
+#else
+ #define INTERNAL_CATCH_MSG( messageType, resultDisposition, macroName, log ) \
+ do { \
+ Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, "", resultDisposition ); \
+ __catchResult << log + ::Catch::StreamEndStop(); \
+ __catchResult.captureResult( messageType ); \
+ INTERNAL_CATCH_REACT( __catchResult ) \
+ } while( Catch::alwaysFalse() )
+#endif
+
+///////////////////////////////////////////////////////////////////////////////
+#define INTERNAL_CATCH_INFO( log, macroName ) \
+ Catch::ScopedMessage INTERNAL_CATCH_UNIQUE_NAME( scopedMessage ) = Catch::MessageBuilder( macroName, CATCH_INTERNAL_LINEINFO, Catch::ResultWas::Info ) << log;
+
+///////////////////////////////////////////////////////////////////////////////
+#define INTERNAL_CHECK_THAT( arg, matcher, resultDisposition, macroName ) \
+ do { \
+ Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, #arg ", " #matcher, resultDisposition ); \
+ try { \
+ std::string matcherAsString = (matcher).toString(); \
+ __catchResult \
+ .setLhs( Catch::toString( arg ) ) \
+ .setRhs( matcherAsString == Catch::Detail::unprintableString ? #matcher : matcherAsString ) \
+ .setOp( "matches" ) \
+ .setResultType( (matcher).match( arg ) ); \
+ __catchResult.captureExpression(); \
+ } catch( ... ) { \
+ __catchResult.useActiveException( resultDisposition | Catch::ResultDisposition::ContinueOnFailure ); \
+ } \
+ INTERNAL_CATCH_REACT( __catchResult ) \
+ } while( Catch::alwaysFalse() )
+
+// #included from: internal/catch_section.h
+#define TWOBLUECUBES_CATCH_SECTION_H_INCLUDED
+
+// #included from: catch_section_info.h
+#define TWOBLUECUBES_CATCH_SECTION_INFO_H_INCLUDED
+
+// #included from: catch_totals.hpp
+#define TWOBLUECUBES_CATCH_TOTALS_HPP_INCLUDED
+
+#include <cstddef>
+
+namespace Catch {
+
+ struct Counts {
+ Counts() : passed( 0 ), failed( 0 ), failedButOk( 0 ) {}
+
+ Counts operator - ( Counts const& other ) const {
+ Counts diff;
+ diff.passed = passed - other.passed;
+ diff.failed = failed - other.failed;
+ diff.failedButOk = failedButOk - other.failedButOk;
+ return diff;
+ }
+ Counts& operator += ( Counts const& other ) {
+ passed += other.passed;
+ failed += other.failed;
+ failedButOk += other.failedButOk;
+ return *this;
+ }
+
+ std::size_t total() const {
+ return passed + failed + failedButOk;
+ }
+ bool allPassed() const {
+ return failed == 0 && failedButOk == 0;
+ }
+ bool allOk() const {
+ return failed == 0;
+ }
+
+ std::size_t passed;
+ std::size_t failed;
+ std::size_t failedButOk;
+ };
+
+ struct Totals {
+
+ Totals operator - ( Totals const& other ) const {
+ Totals diff;
+ diff.assertions = assertions - other.assertions;
+ diff.testCases = testCases - other.testCases;
+ return diff;
+ }
+
+ Totals delta( Totals const& prevTotals ) const {
+ Totals diff = *this - prevTotals;
+ if( diff.assertions.failed > 0 )
+ ++diff.testCases.failed;
+ else if( diff.assertions.failedButOk > 0 )
+ ++diff.testCases.failedButOk;
+ else
+ ++diff.testCases.passed;
+ return diff;
+ }
+
+ Totals& operator += ( Totals const& other ) {
+ assertions += other.assertions;
+ testCases += other.testCases;
+ return *this;
+ }
+
+ Counts assertions;
+ Counts testCases;
+ };
+}
+
+namespace Catch {
+
+ struct SectionInfo {
+ SectionInfo
+ ( SourceLineInfo const& _lineInfo,
+ std::string const& _name,
+ std::string const& _description = std::string() );
+
+ std::string name;
+ std::string description;
+ SourceLineInfo lineInfo;
+ };
+
+ struct SectionEndInfo {
+ SectionEndInfo( SectionInfo const& _sectionInfo, Counts const& _prevAssertions, double _durationInSeconds )
+ : sectionInfo( _sectionInfo ), prevAssertions( _prevAssertions ), durationInSeconds( _durationInSeconds )
+ {}
+
+ SectionInfo sectionInfo;
+ Counts prevAssertions;
+ double durationInSeconds;
+ };
+
+} // end namespace Catch
+
+// #included from: catch_timer.h
+#define TWOBLUECUBES_CATCH_TIMER_H_INCLUDED
+
+#ifdef CATCH_PLATFORM_WINDOWS
+typedef unsigned long long uint64_t;
+#else
+#include <stdint.h>
+#endif
+
+namespace Catch {
+
+ class Timer {
+ public:
+ Timer() : m_ticks( 0 ) {}
+ void start();
+ unsigned int getElapsedMicroseconds() const;
+ unsigned int getElapsedMilliseconds() const;
+ double getElapsedSeconds() const;
+
+ private:
+ uint64_t m_ticks;
+ };
+
+} // namespace Catch
+
+#include <string>
+
+namespace Catch {
+
+ class Section : NonCopyable {
+ public:
+ Section( SectionInfo const& info );
+ ~Section();
+
+ // This indicates whether the section should be executed or not
+ operator bool() const;
+
+ private:
+ SectionInfo m_info;
+
+ std::string m_name;
+ Counts m_assertions;
+ bool m_sectionIncluded;
+ Timer m_timer;
+ };
+
+} // end namespace Catch
+
+#ifdef CATCH_CONFIG_VARIADIC_MACROS
+ #define INTERNAL_CATCH_SECTION( ... ) \
+ if( Catch::Section const& INTERNAL_CATCH_UNIQUE_NAME( catch_internal_Section ) = Catch::SectionInfo( CATCH_INTERNAL_LINEINFO, __VA_ARGS__ ) )
+#else
+ #define INTERNAL_CATCH_SECTION( name, desc ) \
+ if( Catch::Section const& INTERNAL_CATCH_UNIQUE_NAME( catch_internal_Section ) = Catch::SectionInfo( CATCH_INTERNAL_LINEINFO, name, desc ) )
+#endif
+
+// #included from: internal/catch_generators.hpp
+#define TWOBLUECUBES_CATCH_GENERATORS_HPP_INCLUDED
+
+#include <iterator>
+#include <vector>
+#include <string>
+#include <stdlib.h>
+
+namespace Catch {
+
+template<typename T>
+struct IGenerator {
+ virtual ~IGenerator() {}
+ virtual T getValue( std::size_t index ) const = 0;
+ virtual std::size_t size () const = 0;
+};
+
+template<typename T>
+class BetweenGenerator : public IGenerator<T> {
+public:
+ BetweenGenerator( T from, T to ) : m_from( from ), m_to( to ){}
+
+ virtual T getValue( std::size_t index ) const {
+ return m_from+static_cast<int>( index );
+ }
+
+ virtual std::size_t size() const {
+ return static_cast<std::size_t>( 1+m_to-m_from );
+ }
+
+private:
+
+ T m_from;
+ T m_to;
+};
+
+template<typename T>
+class ValuesGenerator : public IGenerator<T> {
+public:
+ ValuesGenerator(){}
+
+ void add( T value ) {
+ m_values.push_back( value );
+ }
+
+ virtual T getValue( std::size_t index ) const {
+ return m_values[index];
+ }
+
+ virtual std::size_t size() const {
+ return m_values.size();
+ }
+
+private:
+ std::vector<T> m_values;
+};
+
+template<typename T>
+class CompositeGenerator {
+public:
+ CompositeGenerator() : m_totalSize( 0 ) {}
+
+ // *** Move semantics, similar to auto_ptr ***
+ CompositeGenerator( CompositeGenerator& other )
+ : m_fileInfo( other.m_fileInfo ),
+ m_totalSize( 0 )
+ {
+ move( other );
+ }
+
+ CompositeGenerator& setFileInfo( const char* fileInfo ) {
+ m_fileInfo = fileInfo;
+ return *this;
+ }
+
+ ~CompositeGenerator() {
+ deleteAll( m_composed );
+ }
+
+ operator T () const {
+ size_t overallIndex = getCurrentContext().getGeneratorIndex( m_fileInfo, m_totalSize );
+
+ typename std::vector<const IGenerator<T>*>::const_iterator it = m_composed.begin();
+ typename std::vector<const IGenerator<T>*>::const_iterator itEnd = m_composed.end();
+ for( size_t index = 0; it != itEnd; ++it )
+ {
+ const IGenerator<T>* generator = *it;
+ if( overallIndex >= index && overallIndex < index + generator->size() )
+ {
+ return generator->getValue( overallIndex-index );
+ }
+ index += generator->size();
+ }
+ CATCH_INTERNAL_ERROR( "Indexed past end of generated range" );
+ return T(); // Suppress spurious "not all control paths return a value" warning in Visual Studio - if you know how to fix this please do so
+ }
+
+ void add( const IGenerator<T>* generator ) {
+ m_totalSize += generator->size();
+ m_composed.push_back( generator );
+ }
+
+ CompositeGenerator& then( CompositeGenerator& other ) {
+ move( other );
+ return *this;
+ }
+
+ CompositeGenerator& then( T value ) {
+ ValuesGenerator<T>* valuesGen = new ValuesGenerator<T>();
+ valuesGen->add( value );
+ add( valuesGen );
+ return *this;
+ }
+
+private:
+
+ void move( CompositeGenerator& other ) {
+ std::copy( other.m_composed.begin(), other.m_composed.end(), std::back_inserter( m_composed ) );
+ m_totalSize += other.m_totalSize;
+ other.m_composed.clear();
+ }
+
+ std::vector<const IGenerator<T>*> m_composed;
+ std::string m_fileInfo;
+ size_t m_totalSize;
+};
+
+namespace Generators
+{
+ template<typename T>
+ CompositeGenerator<T> between( T from, T to ) {
+ CompositeGenerator<T> generators;
+ generators.add( new BetweenGenerator<T>( from, to ) );
+ return generators;
+ }
+
+ template<typename T>
+ CompositeGenerator<T> values( T val1, T val2 ) {
+ CompositeGenerator<T> generators;
+ ValuesGenerator<T>* valuesGen = new ValuesGenerator<T>();
+ valuesGen->add( val1 );
+ valuesGen->add( val2 );
+ generators.add( valuesGen );
+ return generators;
+ }
+
+ template<typename T>
+ CompositeGenerator<T> values( T val1, T val2, T val3 ){
+ CompositeGenerator<T> generators;
+ ValuesGenerator<T>* valuesGen = new ValuesGenerator<T>();
+ valuesGen->add( val1 );
+ valuesGen->add( val2 );
+ valuesGen->add( val3 );
+ generators.add( valuesGen );
+ return generators;
+ }
+
+ template<typename T>
+ CompositeGenerator<T> values( T val1, T val2, T val3, T val4 ) {
+ CompositeGenerator<T> generators;
+ ValuesGenerator<T>* valuesGen = new ValuesGenerator<T>();
+ valuesGen->add( val1 );
+ valuesGen->add( val2 );
+ valuesGen->add( val3 );
+ valuesGen->add( val4 );
+ generators.add( valuesGen );
+ return generators;
+ }
+
+} // end namespace Generators
+
+using namespace Generators;
+
+} // end namespace Catch
+
+#define INTERNAL_CATCH_LINESTR2( line ) #line
+#define INTERNAL_CATCH_LINESTR( line ) INTERNAL_CATCH_LINESTR2( line )
+
+#define INTERNAL_CATCH_GENERATE( expr ) expr.setFileInfo( __FILE__ "(" INTERNAL_CATCH_LINESTR( __LINE__ ) ")" )
+
+// #included from: internal/catch_interfaces_exception.h
+#define TWOBLUECUBES_CATCH_INTERFACES_EXCEPTION_H_INCLUDED
+
+#include <string>
+#include <vector>
+
+// #included from: catch_interfaces_registry_hub.h
+#define TWOBLUECUBES_CATCH_INTERFACES_REGISTRY_HUB_H_INCLUDED
+
+#include <string>
+
+namespace Catch {
+
+ class TestCase;
+ struct ITestCaseRegistry;
+ struct IExceptionTranslatorRegistry;
+ struct IExceptionTranslator;
+ struct IReporterRegistry;
+ struct IReporterFactory;
+
+ struct IRegistryHub {
+ virtual ~IRegistryHub();
+
+ virtual IReporterRegistry const& getReporterRegistry() const = 0;
+ virtual ITestCaseRegistry const& getTestCaseRegistry() const = 0;
+ virtual IExceptionTranslatorRegistry& getExceptionTranslatorRegistry() = 0;
+ };
+
+ struct IMutableRegistryHub {
+ virtual ~IMutableRegistryHub();
+ virtual void registerReporter( std::string const& name, Ptr<IReporterFactory> const& factory ) = 0;
+ virtual void registerListener( Ptr<IReporterFactory> const& factory ) = 0;
+ virtual void registerTest( TestCase const& testInfo ) = 0;
+ virtual void registerTranslator( const IExceptionTranslator* translator ) = 0;
+ };
+
+ IRegistryHub& getRegistryHub();
+ IMutableRegistryHub& getMutableRegistryHub();
+ void cleanUp();
+ std::string translateActiveException();
+
+}
+
+namespace Catch {
+
+ typedef std::string(*exceptionTranslateFunction)();
+
+ struct IExceptionTranslator;
+ typedef std::vector<const IExceptionTranslator*> ExceptionTranslators;
+
+ struct IExceptionTranslator {
+ virtual ~IExceptionTranslator();
+ virtual std::string translate( ExceptionTranslators::const_iterator it, ExceptionTranslators::const_iterator itEnd ) const = 0;
+ };
+
+ struct IExceptionTranslatorRegistry {
+ virtual ~IExceptionTranslatorRegistry();
+
+ virtual std::string translateActiveException() const = 0;
+ };
+
+ class ExceptionTranslatorRegistrar {
+ template<typename T>
+ class ExceptionTranslator : public IExceptionTranslator {
+ public:
+
+ ExceptionTranslator( std::string(*translateFunction)( T& ) )
+ : m_translateFunction( translateFunction )
+ {}
+
+ virtual std::string translate( ExceptionTranslators::const_iterator it, ExceptionTranslators::const_iterator itEnd ) const CATCH_OVERRIDE {
+ try {
+ if( it == itEnd )
+ throw;
+ else
+ return (*it)->translate( it+1, itEnd );
+ }
+ catch( T& ex ) {
+ return m_translateFunction( ex );
+ }
+ }
+
+ protected:
+ std::string(*m_translateFunction)( T& );
+ };
+
+ public:
+ template<typename T>
+ ExceptionTranslatorRegistrar( std::string(*translateFunction)( T& ) ) {
+ getMutableRegistryHub().registerTranslator
+ ( new ExceptionTranslator<T>( translateFunction ) );
+ }
+ };
+}
+
+///////////////////////////////////////////////////////////////////////////////
+#define INTERNAL_CATCH_TRANSLATE_EXCEPTION2( translatorName, signature ) \
+ static std::string translatorName( signature ); \
+ namespace{ Catch::ExceptionTranslatorRegistrar INTERNAL_CATCH_UNIQUE_NAME( catch_internal_ExceptionRegistrar )( &translatorName ); }\
+ static std::string translatorName( signature )
+
+#define INTERNAL_CATCH_TRANSLATE_EXCEPTION( signature ) INTERNAL_CATCH_TRANSLATE_EXCEPTION2( INTERNAL_CATCH_UNIQUE_NAME( catch_internal_ExceptionTranslator ), signature )
+
+// #included from: internal/catch_approx.hpp
+#define TWOBLUECUBES_CATCH_APPROX_HPP_INCLUDED
+
+#include <cmath>
+#include <limits>
+
+namespace Catch {
+namespace Detail {
+
+ class Approx {
+ public:
+ explicit Approx ( double value )
+ : m_epsilon( std::numeric_limits<float>::epsilon()*100 ),
+ m_scale( 1.0 ),
+ m_value( value )
+ {}
+
+ Approx( Approx const& other )
+ : m_epsilon( other.m_epsilon ),
+ m_scale( other.m_scale ),
+ m_value( other.m_value )
+ {}
+
+ static Approx custom() {
+ return Approx( 0 );
+ }
+
+ 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 ) {
+ // Thanks to Richard Harris for his help refining this formula
+ return fabs( lhs - rhs.m_value ) < rhs.m_epsilon * (rhs.m_scale + (std::max)( fabs(lhs), fabs(rhs.m_value) ) );
+ }
+
+ 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;
+ }
+
+ std::string toString() const {
+ std::ostringstream oss;
+ oss << "Approx( " << Catch::toString( m_value ) << " )";
+ return oss.str();
+ }
+
+ private:
+ double m_epsilon;
+ double m_scale;
+ double m_value;
+ };
+}
+
+template<>
+inline std::string toString<Detail::Approx>( Detail::Approx const& value ) {
+ return value.toString();
+}
+
+} // end namespace Catch
+
+// #included from: internal/catch_interfaces_tag_alias_registry.h
+#define TWOBLUECUBES_CATCH_INTERFACES_TAG_ALIAS_REGISTRY_H_INCLUDED
+
+// #included from: catch_tag_alias.h
+#define TWOBLUECUBES_CATCH_TAG_ALIAS_H_INCLUDED
+
+#include <string>
+
+namespace Catch {
+
+ struct TagAlias {
+ TagAlias( std::string _tag, SourceLineInfo _lineInfo ) : tag( _tag ), lineInfo( _lineInfo ) {}
+
+ std::string tag;
+ SourceLineInfo lineInfo;
+ };
+
+ struct RegistrarForTagAliases {
+ RegistrarForTagAliases( char const* alias, char const* tag, SourceLineInfo const& lineInfo );
+ };
+
+} // end namespace Catch
+
+#define CATCH_REGISTER_TAG_ALIAS( alias, spec ) namespace{ Catch::RegistrarForTagAliases INTERNAL_CATCH_UNIQUE_NAME( AutoRegisterTagAlias )( alias, spec, CATCH_INTERNAL_LINEINFO ); }
+// #included from: catch_option.hpp
+#define TWOBLUECUBES_CATCH_OPTION_HPP_INCLUDED
+
+namespace Catch {
+
+ // An optional type
+ template<typename T>
+ class Option {
+ public:
+ Option() : nullableValue( CATCH_NULL ) {}
+ Option( T const& _value )
+ : nullableValue( new( storage ) T( _value ) )
+ {}
+ Option( Option const& _other )
+ : nullableValue( _other ? new( storage ) T( *_other ) : CATCH_NULL )
+ {}
+
+ ~Option() {
+ reset();
+ }
+
+ Option& operator= ( Option const& _other ) {
+ if( &_other != this ) {
+ reset();
+ if( _other )
+ nullableValue = new( storage ) T( *_other );
+ }
+ return *this;
+ }
+ Option& operator = ( T const& _value ) {
+ reset();
+ nullableValue = new( storage ) T( _value );
+ return *this;
+ }
+
+ void reset() {
+ if( nullableValue )
+ nullableValue->~T();
+ nullableValue = CATCH_NULL;
+ }
+
+ T& operator*() { return *nullableValue; }
+ T const& operator*() const { return *nullableValue; }
+ T* operator->() { return nullableValue; }
+ const T* operator->() const { return nullableValue; }
+
+ T valueOr( T const& defaultValue ) const {
+ return nullableValue ? *nullableValue : defaultValue;
+ }
+
+ bool some() const { return nullableValue != CATCH_NULL; }
+ bool none() const { return nullableValue == CATCH_NULL; }
+
+ bool operator !() const { return nullableValue == CATCH_NULL; }
+ operator SafeBool::type() const {
+ return SafeBool::makeSafe( some() );
+ }
+
+ private:
+ T* nullableValue;
+ char storage[sizeof(T)];
+ };
+
+} // end namespace Catch
+
+namespace Catch {
+
+ struct ITagAliasRegistry {
+ virtual ~ITagAliasRegistry();
+ virtual Option<TagAlias> find( std::string const& alias ) const = 0;
+ virtual std::string expandAliases( std::string const& unexpandedTestSpec ) const = 0;
+
+ static ITagAliasRegistry const& get();
+ };
+
+} // end namespace Catch
+
+// These files are included here so the single_include script doesn't put them
+// in the conditionally compiled sections
+// #included from: internal/catch_test_case_info.h
+#define TWOBLUECUBES_CATCH_TEST_CASE_INFO_H_INCLUDED
+
+#include <string>
+#include <set>
+
+#ifdef __clang__
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wpadded"
+#endif
+
+namespace Catch {
+
+ struct ITestCase;
+
+ struct TestCaseInfo {
+ enum SpecialProperties{
+ None = 0,
+ IsHidden = 1 << 1,
+ ShouldFail = 1 << 2,
+ MayFail = 1 << 3,
+ Throws = 1 << 4
+ };
+
+ TestCaseInfo( std::string const& _name,
+ std::string const& _className,
+ std::string const& _description,
+ std::set<std::string> const& _tags,
+ SourceLineInfo const& _lineInfo );
+
+ TestCaseInfo( TestCaseInfo const& other );
+
+ friend void setTags( TestCaseInfo& testCaseInfo, std::set<std::string> const& tags );
+
+ bool isHidden() const;
+ bool throws() const;
+ bool okToFail() const;
+ bool expectedToFail() const;
+
+ std::string name;
+ std::string className;
+ std::string description;
+ std::set<std::string> tags;
+ std::set<std::string> lcaseTags;
+ std::string tagsAsString;
+ SourceLineInfo lineInfo;
+ SpecialProperties properties;
+ };
+
+ class TestCase : public TestCaseInfo {
+ public:
+
+ TestCase( ITestCase* testCase, TestCaseInfo const& info );
+ TestCase( TestCase const& other );
+
+ TestCase withName( std::string const& _newName ) const;
+
+ void invoke() const;
+
+ TestCaseInfo const& getTestCaseInfo() const;
+
+ void swap( TestCase& other );
+ bool operator == ( TestCase const& other ) const;
+ bool operator < ( TestCase const& other ) const;
+ TestCase& operator = ( TestCase const& other );
+
+ private:
+ Ptr<ITestCase> test;
+ };
+
+ TestCase makeTestCase( ITestCase* testCase,
+ std::string const& className,
+ std::string const& name,
+ std::string const& description,
+ SourceLineInfo const& lineInfo );
+}
+
+#ifdef __clang__
+#pragma clang diagnostic pop
+#endif
+
+
+#ifdef __OBJC__
+// #included from: internal/catch_objc.hpp
+#define TWOBLUECUBES_CATCH_OBJC_HPP_INCLUDED
+
+#import <objc/runtime.h>
+
+#include <string>
+
+// NB. Any general catch headers included here must be included
+// in catch.hpp first to make sure they are included by the single
+// header for non obj-usage
+
+///////////////////////////////////////////////////////////////////////////////
+// This protocol is really only here for (self) documenting purposes, since
+// all its methods are optional.
+@protocol OcFixture
+
+@optional
+
+-(void) setUp;
+-(void) tearDown;
+
+@end
+
+namespace Catch {
+
+ class OcMethod : public SharedImpl<ITestCase> {
+
+ public:
+ OcMethod( Class cls, SEL sel ) : m_cls( cls ), m_sel( sel ) {}
+
+ virtual void invoke() const {
+ id obj = [[m_cls alloc] init];
+
+ performOptionalSelector( obj, @selector(setUp) );
+ performOptionalSelector( obj, m_sel );
+ performOptionalSelector( obj, @selector(tearDown) );
+
+ arcSafeRelease( obj );
+ }
+ private:
+ virtual ~OcMethod() {}
+
+ Class m_cls;
+ SEL m_sel;
+ };
+
+ namespace Detail{
+
+ inline std::string getAnnotation( Class cls,
+ std::string const& annotationName,
+ std::string const& testCaseName ) {
+ NSString* selStr = [[NSString alloc] initWithFormat:@"Catch_%s_%s", annotationName.c_str(), testCaseName.c_str()];
+ SEL sel = NSSelectorFromString( selStr );
+ arcSafeRelease( selStr );
+ id value = performOptionalSelector( cls, sel );
+ if( value )
+ return [(NSString*)value UTF8String];
+ return "";
+ }
+ }
+
+ inline size_t registerTestMethods() {
+ size_t noTestMethods = 0;
+ int noClasses = objc_getClassList( CATCH_NULL, 0 );
+
+ Class* classes = (CATCH_UNSAFE_UNRETAINED Class *)malloc( sizeof(Class) * noClasses);
+ objc_getClassList( classes, noClasses );
+
+ for( int c = 0; c < noClasses; c++ ) {
+ Class cls = classes[c];
+ {
+ u_int count;
+ Method* methods = class_copyMethodList( cls, &count );
+ for( u_int m = 0; m < count ; m++ ) {
+ SEL selector = method_getName(methods[m]);
+ std::string methodName = sel_getName(selector);
+ if( startsWith( methodName, "Catch_TestCase_" ) ) {
+ std::string testCaseName = methodName.substr( 15 );
+ std::string name = Detail::getAnnotation( cls, "Name", testCaseName );
+ std::string desc = Detail::getAnnotation( cls, "Description", testCaseName );
+ const char* className = class_getName( cls );
+
+ getMutableRegistryHub().registerTest( makeTestCase( new OcMethod( cls, selector ), className, name.c_str(), desc.c_str(), SourceLineInfo() ) );
+ noTestMethods++;
+ }
+ }
+ free(methods);
+ }
+ }
+ return noTestMethods;
+ }
+
+ namespace Matchers {
+ namespace Impl {
+ namespace NSStringMatchers {
+
+ template<typename MatcherT>
+ struct StringHolder : MatcherImpl<MatcherT, NSString*>{
+ StringHolder( NSString* substr ) : m_substr( [substr copy] ){}
+ StringHolder( StringHolder const& other ) : m_substr( [other.m_substr copy] ){}
+ StringHolder() {
+ arcSafeRelease( m_substr );
+ }
+
+ NSString* m_substr;
+ };
+
+ struct Equals : StringHolder<Equals> {
+ Equals( NSString* substr ) : StringHolder( substr ){}
+
+ virtual bool match( ExpressionType const& str ) const {
+ return (str != nil || m_substr == nil ) &&
+ [str isEqualToString:m_substr];
+ }
+
+ virtual std::string toString() const {
+ return "equals string: " + Catch::toString( m_substr );
+ }
+ };
+
+ struct Contains : StringHolder<Contains> {
+ Contains( NSString* substr ) : StringHolder( substr ){}
+
+ virtual bool match( ExpressionType const& str ) const {
+ return (str != nil || m_substr == nil ) &&
+ [str rangeOfString:m_substr].location != NSNotFound;
+ }
+
+ virtual std::string toString() const {
+ return "contains string: " + Catch::toString( m_substr );
+ }
+ };
+
+ struct StartsWith : StringHolder<StartsWith> {
+ StartsWith( NSString* substr ) : StringHolder( substr ){}
+
+ virtual bool match( ExpressionType const& str ) const {
+ return (str != nil || m_substr == nil ) &&
+ [str rangeOfString:m_substr].location == 0;
+ }
+
+ virtual std::string toString() const {
+ return "starts with: " + Catch::toString( m_substr );
+ }
+ };
+ struct EndsWith : StringHolder<EndsWith> {
+ EndsWith( NSString* substr ) : StringHolder( substr ){}
+
+ virtual bool match( ExpressionType const& str ) const {
+ return (str != nil || m_substr == nil ) &&
+ [str rangeOfString:m_substr].location == [str length] - [m_substr length];
+ }
+
+ virtual std::string toString() const {
+ return "ends with: " + Catch::toString( m_substr );
+ }
+ };
+
+ } // namespace NSStringMatchers
+ } // namespace Impl
+
+ inline Impl::NSStringMatchers::Equals
+ Equals( NSString* substr ){ return Impl::NSStringMatchers::Equals( substr ); }
+
+ inline Impl::NSStringMatchers::Contains
+ Contains( NSString* substr ){ return Impl::NSStringMatchers::Contains( substr ); }
+
+ inline Impl::NSStringMatchers::StartsWith
+ StartsWith( NSString* substr ){ return Impl::NSStringMatchers::StartsWith( substr ); }
+
+ inline Impl::NSStringMatchers::EndsWith
+ EndsWith( NSString* substr ){ return Impl::NSStringMatchers::EndsWith( substr ); }
+
+ } // namespace Matchers
+
+ using namespace Matchers;
+
+} // namespace Catch
+
+///////////////////////////////////////////////////////////////////////////////
+#define OC_TEST_CASE( name, desc )\
++(NSString*) INTERNAL_CATCH_UNIQUE_NAME( Catch_Name_test ) \
+{\
+return @ name; \
+}\
++(NSString*) INTERNAL_CATCH_UNIQUE_NAME( Catch_Description_test ) \
+{ \
+return @ desc; \
+} \
+-(void) INTERNAL_CATCH_UNIQUE_NAME( Catch_TestCase_test )
+
+#endif
+
+#ifdef CATCH_IMPL
+// #included from: internal/catch_impl.hpp
+#define TWOBLUECUBES_CATCH_IMPL_HPP_INCLUDED
+
+// Collect all the implementation files together here
+// These are the equivalent of what would usually be cpp files
+
+#ifdef __clang__
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wweak-vtables"
+#endif
+
+// #included from: ../catch_session.hpp
+#define TWOBLUECUBES_CATCH_RUNNER_HPP_INCLUDED
+
+// #included from: internal/catch_commandline.hpp
+#define TWOBLUECUBES_CATCH_COMMANDLINE_HPP_INCLUDED
+
+// #included from: catch_config.hpp
+#define TWOBLUECUBES_CATCH_CONFIG_HPP_INCLUDED
+
+// #included from: catch_test_spec_parser.hpp
+#define TWOBLUECUBES_CATCH_TEST_SPEC_PARSER_HPP_INCLUDED
+
+#ifdef __clang__
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wpadded"
+#endif
+
+// #included from: catch_test_spec.hpp
+#define TWOBLUECUBES_CATCH_TEST_SPEC_HPP_INCLUDED
+
+#ifdef __clang__
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wpadded"
+#endif
+
+// #included from: catch_wildcard_pattern.hpp
+#define TWOBLUECUBES_CATCH_WILDCARD_PATTERN_HPP_INCLUDED
+
+namespace Catch
+{
+ class WildcardPattern {
+ enum WildcardPosition {
+ NoWildcard = 0,
+ WildcardAtStart = 1,
+ WildcardAtEnd = 2,
+ WildcardAtBothEnds = WildcardAtStart | WildcardAtEnd
+ };
+
+ public:
+
+ WildcardPattern( std::string const& pattern, CaseSensitive::Choice caseSensitivity )
+ : m_caseSensitivity( caseSensitivity ),
+ m_wildcard( NoWildcard ),
+ m_pattern( adjustCase( pattern ) )
+ {
+ if( startsWith( m_pattern, "*" ) ) {
+ m_pattern = m_pattern.substr( 1 );
+ m_wildcard = WildcardAtStart;
+ }
+ if( endsWith( m_pattern, "*" ) ) {
+ m_pattern = m_pattern.substr( 0, m_pattern.size()-1 );
+ m_wildcard = static_cast<WildcardPosition>( m_wildcard | WildcardAtEnd );
+ }
+ }
+ virtual ~WildcardPattern();
+ virtual bool matches( std::string const& str ) const {
+ switch( m_wildcard ) {
+ case NoWildcard:
+ return m_pattern == adjustCase( str );
+ case WildcardAtStart:
+ return endsWith( adjustCase( str ), m_pattern );
+ case WildcardAtEnd:
+ return startsWith( adjustCase( str ), m_pattern );
+ case WildcardAtBothEnds:
+ return contains( adjustCase( str ), m_pattern );
+ }
+
+#ifdef __clang__
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wunreachable-code"
+#endif
+ throw std::logic_error( "Unknown enum" );
+#ifdef __clang__
+#pragma clang diagnostic pop
+#endif
+ }
+ private:
+ std::string adjustCase( std::string const& str ) const {
+ return m_caseSensitivity == CaseSensitive::No ? toLower( str ) : str;
+ }
+ CaseSensitive::Choice m_caseSensitivity;
+ WildcardPosition m_wildcard;
+ std::string m_pattern;
+ };
+}
+
+#include <string>
+#include <vector>
+
+namespace Catch {
+
+ class TestSpec {
+ struct Pattern : SharedImpl<> {
+ virtual ~Pattern();
+ virtual bool matches( TestCaseInfo const& testCase ) const = 0;
+ };
+ class NamePattern : public Pattern {
+ public:
+ NamePattern( std::string const& name )
+ : m_wildcardPattern( toLower( name ), CaseSensitive::No )
+ {}
+ virtual ~NamePattern();
+ virtual bool matches( TestCaseInfo const& testCase ) const {
+ return m_wildcardPattern.matches( toLower( testCase.name ) );
+ }
+ private:
+ WildcardPattern m_wildcardPattern;
+ };
+
+ class TagPattern : public Pattern {
+ public:
+ TagPattern( std::string const& tag ) : m_tag( toLower( tag ) ) {}
+ virtual ~TagPattern();
+ virtual bool matches( TestCaseInfo const& testCase ) const {
+ return testCase.lcaseTags.find( m_tag ) != testCase.lcaseTags.end();
+ }
+ private:
+ std::string m_tag;
+ };
+
+ class ExcludedPattern : public Pattern {
+ public:
+ ExcludedPattern( Ptr<Pattern> const& underlyingPattern ) : m_underlyingPattern( underlyingPattern ) {}
+ virtual ~ExcludedPattern();
+ virtual bool matches( TestCaseInfo const& testCase ) const { return !m_underlyingPattern->matches( testCase ); }
+ private:
+ Ptr<Pattern> m_underlyingPattern;
+ };
+
+ struct Filter {
+ std::vector<Ptr<Pattern> > m_patterns;
+
+ bool matches( TestCaseInfo const& testCase ) const {
+ // All patterns in a filter must match for the filter to be a match
+ for( std::vector<Ptr<Pattern> >::const_iterator it = m_patterns.begin(), itEnd = m_patterns.end(); it != itEnd; ++it )
+ if( !(*it)->matches( testCase ) )
+ return false;
+ return true;
+ }
+ };
+
+ public:
+ bool hasFilters() const {
+ return !m_filters.empty();
+ }
+ bool matches( TestCaseInfo const& testCase ) const {
+ // A TestSpec matches if any filter matches
+ for( std::vector<Filter>::const_iterator it = m_filters.begin(), itEnd = m_filters.end(); it != itEnd; ++it )
+ if( it->matches( testCase ) )
+ return true;
+ return false;
+ }
+
+ private:
+ std::vector<Filter> m_filters;
+
+ friend class TestSpecParser;
+ };
+}
+
+#ifdef __clang__
+#pragma clang diagnostic pop
+#endif
+
+namespace Catch {
+
+ class TestSpecParser {
+ enum Mode{ None, Name, QuotedName, Tag };
+ Mode m_mode;
+ bool m_exclusion;
+ std::size_t m_start, m_pos;
+ std::string m_arg;
+ TestSpec::Filter m_currentFilter;
+ TestSpec m_testSpec;
+ ITagAliasRegistry const* m_tagAliases;
+
+ public:
+ TestSpecParser( ITagAliasRegistry const& tagAliases ) : m_tagAliases( &tagAliases ) {}
+
+ TestSpecParser& parse( std::string const& arg ) {
+ m_mode = None;
+ m_exclusion = false;
+ m_start = std::string::npos;
+ m_arg = m_tagAliases->expandAliases( arg );
+ for( m_pos = 0; m_pos < m_arg.size(); ++m_pos )
+ visitChar( m_arg[m_pos] );
+ if( m_mode == Name )
+ addPattern<TestSpec::NamePattern>();
+ return *this;
+ }
+ TestSpec testSpec() {
+ addFilter();
+ return m_testSpec;
+ }
+ private:
+ void visitChar( char c ) {
+ if( m_mode == None ) {
+ switch( c ) {
+ case ' ': return;
+ case '~': m_exclusion = true; return;
+ case '[': return startNewMode( Tag, ++m_pos );
+ case '"': return startNewMode( QuotedName, ++m_pos );
+ default: startNewMode( Name, m_pos ); break;
+ }
+ }
+ if( m_mode == Name ) {
+ if( c == ',' ) {
+ addPattern<TestSpec::NamePattern>();
+ addFilter();
+ }
+ else if( c == '[' ) {
+ if( subString() == "exclude:" )
+ m_exclusion = true;
+ else
+ addPattern<TestSpec::NamePattern>();
+ startNewMode( Tag, ++m_pos );
+ }
+ }
+ else if( m_mode == QuotedName && c == '"' )
+ addPattern<TestSpec::NamePattern>();
+ else if( m_mode == Tag && c == ']' )
+ addPattern<TestSpec::TagPattern>();
+ }
+ void startNewMode( Mode mode, std::size_t start ) {
+ m_mode = mode;
+ m_start = start;
+ }
+ std::string subString() const { return m_arg.substr( m_start, m_pos - m_start ); }
+ template<typename T>
+ void addPattern() {
+ std::string token = subString();
+ if( startsWith( token, "exclude:" ) ) {
+ m_exclusion = true;
+ token = token.substr( 8 );
+ }
+ if( !token.empty() ) {
+ Ptr<TestSpec::Pattern> pattern = new T( token );
+ if( m_exclusion )
+ pattern = new TestSpec::ExcludedPattern( pattern );
+ m_currentFilter.m_patterns.push_back( pattern );
+ }
+ m_exclusion = false;
+ m_mode = None;
+ }
+ void addFilter() {
+ if( !m_currentFilter.m_patterns.empty() ) {
+ m_testSpec.m_filters.push_back( m_currentFilter );
+ m_currentFilter = TestSpec::Filter();
+ }
+ }
+ };
+ inline TestSpec parseTestSpec( std::string const& arg ) {
+ return TestSpecParser( ITagAliasRegistry::get() ).parse( arg ).testSpec();
+ }
+
+} // namespace Catch
+
+#ifdef __clang__
+#pragma clang diagnostic pop
+#endif
+
+// #included from: catch_interfaces_config.h
+#define TWOBLUECUBES_CATCH_INTERFACES_CONFIG_H_INCLUDED
+
+#include <iostream>
+#include <string>
+#include <vector>
+
+namespace Catch {
+
+ struct Verbosity { enum Level {
+ NoOutput = 0,
+ Quiet,
+ Normal
+ }; };
+
+ struct WarnAbout { enum What {
+ Nothing = 0x00,
+ NoAssertions = 0x01
+ }; };
+
+ struct ShowDurations { enum OrNot {
+ DefaultForReporter,
+ Always,
+ Never
+ }; };
+ struct RunTests { enum InWhatOrder {
+ InDeclarationOrder,
+ InLexicographicalOrder,
+ InRandomOrder
+ }; };
+ struct UseColour { enum YesOrNo {
+ Auto,
+ Yes,
+ No
+ }; };
+
+ class TestSpec;
+
+ struct IConfig : IShared {
+
+ virtual ~IConfig();
+
+ virtual bool allowThrows() const = 0;
+ virtual std::ostream& stream() const = 0;
+ virtual std::string name() const = 0;
+ virtual bool includeSuccessfulResults() const = 0;
+ virtual bool shouldDebugBreak() const = 0;
+ virtual bool warnAboutMissingAssertions() const = 0;
+ virtual int abortAfter() const = 0;
+ virtual bool showInvisibles() const = 0;
+ virtual ShowDurations::OrNot showDurations() const = 0;
+ virtual TestSpec const& testSpec() const = 0;
+ virtual RunTests::InWhatOrder runOrder() const = 0;
+ virtual unsigned int rngSeed() const = 0;
+ virtual UseColour::YesOrNo useColour() const = 0;
+ };
+}
+
+// #included from: catch_stream.h
+#define TWOBLUECUBES_CATCH_STREAM_H_INCLUDED
+
+// #included from: catch_streambuf.h
+#define TWOBLUECUBES_CATCH_STREAMBUF_H_INCLUDED
+
+#include <streambuf>
+
+namespace Catch {
+
+ class StreamBufBase : public std::streambuf {
+ public:
+ virtual ~StreamBufBase() CATCH_NOEXCEPT;
+ };
+}
+
+#include <streambuf>
+#include <ostream>
+#include <fstream>
+
+namespace Catch {
+
+ std::ostream& cout();
+ std::ostream& cerr();
+
+ struct IStream {
+ virtual ~IStream() CATCH_NOEXCEPT;
+ virtual std::ostream& stream() const = 0;
+ };
+
+ class FileStream : public IStream {
+ mutable std::ofstream m_ofs;
+ public:
+ FileStream( std::string const& filename );
+ virtual ~FileStream() CATCH_NOEXCEPT;
+ public: // IStream
+ virtual std::ostream& stream() const CATCH_OVERRIDE;
+ };
+
+ class CoutStream : public IStream {
+ mutable std::ostream m_os;
+ public:
+ CoutStream();
+ virtual ~CoutStream() CATCH_NOEXCEPT;
+
+ public: // IStream
+ virtual std::ostream& stream() const CATCH_OVERRIDE;
+ };
+
+ class DebugOutStream : public IStream {
+ std::auto_ptr<StreamBufBase> m_streamBuf;
+ mutable std::ostream m_os;
+ public:
+ DebugOutStream();
+ virtual ~DebugOutStream() CATCH_NOEXCEPT;
+
+ public: // IStream
+ virtual std::ostream& stream() const CATCH_OVERRIDE;
+ };
+}
+
+#include <memory>
+#include <vector>
+#include <string>
+#include <iostream>
+#include <ctime>
+
+#ifndef CATCH_CONFIG_CONSOLE_WIDTH
+#define CATCH_CONFIG_CONSOLE_WIDTH 80
+#endif
+
+namespace Catch {
+
+ struct ConfigData {
+
+ ConfigData()
+ : listTests( false ),
+ listTags( false ),
+ listReporters( false ),
+ listTestNamesOnly( false ),
+ showSuccessfulTests( false ),
+ shouldDebugBreak( false ),
+ noThrow( false ),
+ showHelp( false ),
+ showInvisibles( false ),
+ filenamesAsTags( false ),
+ abortAfter( -1 ),
+ rngSeed( 0 ),
+ verbosity( Verbosity::Normal ),
+ warnings( WarnAbout::Nothing ),
+ showDurations( ShowDurations::DefaultForReporter ),
+ runOrder( RunTests::InDeclarationOrder ),
+ useColour( UseColour::Auto )
+ {}
+
+ bool listTests;
+ bool listTags;
+ bool listReporters;
+ bool listTestNamesOnly;
+
+ bool showSuccessfulTests;
+ bool shouldDebugBreak;
+ bool noThrow;
+ bool showHelp;
+ bool showInvisibles;
+ bool filenamesAsTags;
+
+ int abortAfter;
+ unsigned int rngSeed;
+
+ Verbosity::Level verbosity;
+ WarnAbout::What warnings;
+ ShowDurations::OrNot showDurations;
+ RunTests::InWhatOrder runOrder;
+ UseColour::YesOrNo useColour;
+
+ std::string outputFilename;
+ std::string name;
+ std::string processName;
+
+ std::vector<std::string> reporterNames;
+ std::vector<std::string> testsOrTags;
+ };
+
+ class Config : public SharedImpl<IConfig> {
+ private:
+ Config( Config const& other );
+ Config& operator = ( Config const& other );
+ virtual void dummy();
+ public:
+
+ Config()
+ {}
+
+ Config( ConfigData const& data )
+ : m_data( data ),
+ m_stream( openStream() )
+ {
+ if( !data.testsOrTags.empty() ) {
+ TestSpecParser parser( ITagAliasRegistry::get() );
+ for( std::size_t i = 0; i < data.testsOrTags.size(); ++i )
+ parser.parse( data.testsOrTags[i] );
+ m_testSpec = parser.testSpec();
+ }
+ }
+
+ virtual ~Config() {
+ }
+
+ std::string const& getFilename() const {
+ return m_data.outputFilename ;
+ }
+
+ bool listTests() const { return m_data.listTests; }
+ bool listTestNamesOnly() const { return m_data.listTestNamesOnly; }
+ bool listTags() const { return m_data.listTags; }
+ bool listReporters() const { return m_data.listReporters; }
+
+ std::string getProcessName() const { return m_data.processName; }
+
+ bool shouldDebugBreak() const { return m_data.shouldDebugBreak; }
+
+ std::vector<std::string> getReporterNames() const { return m_data.reporterNames; }
+
+ int abortAfter() const { return m_data.abortAfter; }
+
+ TestSpec const& testSpec() const { return m_testSpec; }
+
+ bool showHelp() const { return m_data.showHelp; }
+ bool showInvisibles() const { return m_data.showInvisibles; }
+
+ // IConfig interface
+ virtual bool allowThrows() const { return !m_data.noThrow; }
+ virtual std::ostream& stream() const { return m_stream->stream(); }
+ virtual std::string name() const { return m_data.name.empty() ? m_data.processName : m_data.name; }
+ virtual bool includeSuccessfulResults() const { return m_data.showSuccessfulTests; }
+ virtual bool warnAboutMissingAssertions() const { return m_data.warnings & WarnAbout::NoAssertions; }
+ virtual ShowDurations::OrNot showDurations() const { return m_data.showDurations; }
+ virtual RunTests::InWhatOrder runOrder() const { return m_data.runOrder; }
+ virtual unsigned int rngSeed() const { return m_data.rngSeed; }
+ virtual UseColour::YesOrNo useColour() const { return m_data.useColour; }
+
+ private:
+
+ IStream const* openStream() {
+ if( m_data.outputFilename.empty() )
+ return new CoutStream();
+ else if( m_data.outputFilename[0] == '%' ) {
+ if( m_data.outputFilename == "%debug" )
+ return new DebugOutStream();
+ else
+ throw std::domain_error( "Unrecognised stream: " + m_data.outputFilename );
+ }
+ else
+ return new FileStream( m_data.outputFilename );
+ }
+ ConfigData m_data;
+
+ std::auto_ptr<IStream const> m_stream;
+ TestSpec m_testSpec;
+ };
+
+} // end namespace Catch
+
+// #included from: catch_clara.h
+#define TWOBLUECUBES_CATCH_CLARA_H_INCLUDED
+
+// Use Catch's value for console width (store Clara's off to the side, if present)
+#ifdef CLARA_CONFIG_CONSOLE_WIDTH
+#define CATCH_TEMP_CLARA_CONFIG_CONSOLE_WIDTH CLARA_CONFIG_CONSOLE_WIDTH
+#undef CLARA_CONFIG_CONSOLE_WIDTH
+#endif
+#define CLARA_CONFIG_CONSOLE_WIDTH CATCH_CONFIG_CONSOLE_WIDTH
+
+// Declare Clara inside the Catch namespace
+#define STITCH_CLARA_OPEN_NAMESPACE namespace Catch {
+// #included from: ../external/clara.h
+
+// Version 0.0.2.4
+
+// Only use header guard if we are not using an outer namespace
+#if !defined(TWOBLUECUBES_CLARA_H_INCLUDED) || defined(STITCH_CLARA_OPEN_NAMESPACE)
+
+#ifndef STITCH_CLARA_OPEN_NAMESPACE
+#define TWOBLUECUBES_CLARA_H_INCLUDED
+#define STITCH_CLARA_OPEN_NAMESPACE
+#define STITCH_CLARA_CLOSE_NAMESPACE
+#else
+#define STITCH_CLARA_CLOSE_NAMESPACE }
+#endif
+
+#define STITCH_TBC_TEXT_FORMAT_OPEN_NAMESPACE STITCH_CLARA_OPEN_NAMESPACE
+
+// ----------- #included from tbc_text_format.h -----------
+
+// Only use header guard if we are not using an outer namespace
+#if !defined(TBC_TEXT_FORMAT_H_INCLUDED) || defined(STITCH_TBC_TEXT_FORMAT_OUTER_NAMESPACE)
+#ifndef STITCH_TBC_TEXT_FORMAT_OUTER_NAMESPACE
+#define TBC_TEXT_FORMAT_H_INCLUDED
+#endif
+
+#include <string>
+#include <vector>
+#include <sstream>
+#include <algorithm>
+
+// Use optional outer namespace
+#ifdef STITCH_TBC_TEXT_FORMAT_OUTER_NAMESPACE
+namespace STITCH_TBC_TEXT_FORMAT_OUTER_NAMESPACE {
+#endif
+
+namespace Tbc {
+
+#ifdef TBC_TEXT_FORMAT_CONSOLE_WIDTH
+ const unsigned int consoleWidth = TBC_TEXT_FORMAT_CONSOLE_WIDTH;
+#else
+ const unsigned int consoleWidth = 80;
+#endif
+
+ struct TextAttributes {
+ TextAttributes()
+ : initialIndent( std::string::npos ),
+ indent( 0 ),
+ width( consoleWidth-1 ),
+ tabChar( '\t' )
+ {}
+
+ TextAttributes& setInitialIndent( std::size_t _value ) { initialIndent = _value; return *this; }
+ TextAttributes& setIndent( std::size_t _value ) { indent = _value; return *this; }
+ TextAttributes& setWidth( std::size_t _value ) { width = _value; return *this; }
+ TextAttributes& setTabChar( char _value ) { tabChar = _value; return *this; }
+
+ std::size_t initialIndent; // indent of first line, or npos
+ std::size_t indent; // indent of subsequent lines, or all if initialIndent is npos
+ std::size_t width; // maximum width of text, including indent. Longer text will wrap
+ char tabChar; // If this char is seen the indent is changed to current pos
+ };
+
+ class Text {
+ public:
+ Text( std::string const& _str, TextAttributes const& _attr = TextAttributes() )
+ : attr( _attr )
+ {
+ std::string wrappableChars = " [({.,/|\\-";
+ std::size_t indent = _attr.initialIndent != std::string::npos
+ ? _attr.initialIndent
+ : _attr.indent;
+ std::string remainder = _str;
+
+ while( !remainder.empty() ) {
+ if( lines.size() >= 1000 ) {
+ lines.push_back( "... message truncated due to excessive size" );
+ return;
+ }
+ std::size_t tabPos = std::string::npos;
+ std::size_t width = (std::min)( remainder.size(), _attr.width - indent );
+ std::size_t pos = remainder.find_first_of( '\n' );
+ if( pos <= width ) {
+ width = pos;
+ }
+ pos = remainder.find_last_of( _attr.tabChar, width );
+ if( pos != std::string::npos ) {
+ tabPos = pos;
+ if( remainder[width] == '\n' )
+ width--;
+ remainder = remainder.substr( 0, tabPos ) + remainder.substr( tabPos+1 );
+ }
+
+ if( width == remainder.size() ) {
+ spliceLine( indent, remainder, width );
+ }
+ else if( remainder[width] == '\n' ) {
+ spliceLine( indent, remainder, width );
+ if( width <= 1 || remainder.size() != 1 )
+ remainder = remainder.substr( 1 );
+ indent = _attr.indent;
+ }
+ else {
+ pos = remainder.find_last_of( wrappableChars, width );
+ if( pos != std::string::npos && pos > 0 ) {
+ spliceLine( indent, remainder, pos );
+ if( remainder[0] == ' ' )
+ remainder = remainder.substr( 1 );
+ }
+ else {
+ spliceLine( indent, remainder, width-1 );
+ lines.back() += "-";
+ }
+ if( lines.size() == 1 )
+ indent = _attr.indent;
+ if( tabPos != std::string::npos )
+ indent += tabPos;
+ }
+ }
+ }
+
+ void spliceLine( std::size_t _indent, std::string& _remainder, std::size_t _pos ) {
+ lines.push_back( std::string( _indent, ' ' ) + _remainder.substr( 0, _pos ) );
+ _remainder = _remainder.substr( _pos );
+ }
+
+ typedef std::vector<std::string>::const_iterator const_iterator;
+
+ const_iterator begin() const { return lines.begin(); }
+ const_iterator end() const { return lines.end(); }
+ std::string const& last() const { return lines.back(); }
+ std::size_t size() const { return lines.size(); }
+ std::string const& operator[]( std::size_t _index ) const { return lines[_index]; }
+ std::string toString() const {
+ std::ostringstream oss;
+ oss << *this;
+ return oss.str();
+ }
+
+ inline friend std::ostream& operator << ( std::ostream& _stream, Text const& _text ) {
+ for( Text::const_iterator it = _text.begin(), itEnd = _text.end();
+ it != itEnd; ++it ) {
+ if( it != _text.begin() )
+ _stream << "\n";
+ _stream << *it;
+ }
+ return _stream;
+ }
+
+ private:
+ std::string str;
+ TextAttributes attr;
+ std::vector<std::string> lines;
+ };
+
+} // end namespace Tbc
+
+#ifdef STITCH_TBC_TEXT_FORMAT_OUTER_NAMESPACE
+} // end outer namespace
+#endif
+
+#endif // TBC_TEXT_FORMAT_H_INCLUDED
+
+// ----------- end of #include from tbc_text_format.h -----------
+// ........... back in clara.h
+
+#undef STITCH_TBC_TEXT_FORMAT_OPEN_NAMESPACE
+
+// ----------- #included from clara_compilers.h -----------
+
+#ifndef TWOBLUECUBES_CLARA_COMPILERS_H_INCLUDED
+#define TWOBLUECUBES_CLARA_COMPILERS_H_INCLUDED
+
+// Detect a number of compiler features - mostly C++11/14 conformance - by compiler
+// The following features are defined:
+//
+// CLARA_CONFIG_CPP11_NULLPTR : is nullptr supported?
+// CLARA_CONFIG_CPP11_NOEXCEPT : is noexcept supported?
+// CLARA_CONFIG_CPP11_GENERATED_METHODS : The delete and default keywords for compiler generated methods
+// CLARA_CONFIG_CPP11_OVERRIDE : is override supported?
+// CLARA_CONFIG_CPP11_UNIQUE_PTR : is unique_ptr supported (otherwise use auto_ptr)
+
+// CLARA_CONFIG_CPP11_OR_GREATER : Is C++11 supported?
+
+// CLARA_CONFIG_VARIADIC_MACROS : are variadic macros supported?
+
+// In general each macro has a _NO_<feature name> form
+// (e.g. CLARA_CONFIG_CPP11_NO_NULLPTR) which disables the feature.
+// Many features, at point of detection, define an _INTERNAL_ macro, so they
+// can be combined, en-mass, with the _NO_ forms later.
+
+// All the C++11 features can be disabled with CLARA_CONFIG_NO_CPP11
+
+#ifdef __clang__
+
+#if __has_feature(cxx_nullptr)
+#define CLARA_INTERNAL_CONFIG_CPP11_NULLPTR
+#endif
+
+#if __has_feature(cxx_noexcept)
+#define CLARA_INTERNAL_CONFIG_CPP11_NOEXCEPT
+#endif
+
+#endif // __clang__
+
+////////////////////////////////////////////////////////////////////////////////
+// GCC
+#ifdef __GNUC__
+
+#if __GNUC__ == 4 && __GNUC_MINOR__ >= 6 && defined(__GXX_EXPERIMENTAL_CXX0X__)
+#define CLARA_INTERNAL_CONFIG_CPP11_NULLPTR
+#endif
+
+// - otherwise more recent versions define __cplusplus >= 201103L
+// and will get picked up below
+
+#endif // __GNUC__
+
+////////////////////////////////////////////////////////////////////////////////
+// Visual C++
+#ifdef _MSC_VER
+
+#if (_MSC_VER >= 1600)
+#define CLARA_INTERNAL_CONFIG_CPP11_NULLPTR
+#define CLARA_INTERNAL_CONFIG_CPP11_UNIQUE_PTR
+#endif
+
+#if (_MSC_VER >= 1900 ) // (VC++ 13 (VS2015))
+#define CLARA_INTERNAL_CONFIG_CPP11_NOEXCEPT
+#define CLARA_INTERNAL_CONFIG_CPP11_GENERATED_METHODS
+#endif
+
+#endif // _MSC_VER
+
+////////////////////////////////////////////////////////////////////////////////
+// C++ language feature support
+
+// catch all support for C++11
+#if defined(__cplusplus) && __cplusplus >= 201103L
+
+#define CLARA_CPP11_OR_GREATER
+
+#if !defined(CLARA_INTERNAL_CONFIG_CPP11_NULLPTR)
+#define CLARA_INTERNAL_CONFIG_CPP11_NULLPTR
+#endif
+
+#ifndef CLARA_INTERNAL_CONFIG_CPP11_NOEXCEPT
+#define CLARA_INTERNAL_CONFIG_CPP11_NOEXCEPT
+#endif
+
+#ifndef CLARA_INTERNAL_CONFIG_CPP11_GENERATED_METHODS
+#define CLARA_INTERNAL_CONFIG_CPP11_GENERATED_METHODS
+#endif
+
+#if !defined(CLARA_INTERNAL_CONFIG_CPP11_OVERRIDE)
+#define CLARA_INTERNAL_CONFIG_CPP11_OVERRIDE
+#endif
+#if !defined(CLARA_INTERNAL_CONFIG_CPP11_UNIQUE_PTR)
+#define CLARA_INTERNAL_CONFIG_CPP11_UNIQUE_PTR
+#endif
+
+#endif // __cplusplus >= 201103L
+
+// Now set the actual defines based on the above + anything the user has configured
+#if defined(CLARA_INTERNAL_CONFIG_CPP11_NULLPTR) && !defined(CLARA_CONFIG_CPP11_NO_NULLPTR) && !defined(CLARA_CONFIG_CPP11_NULLPTR) && !defined(CLARA_CONFIG_NO_CPP11)
+#define CLARA_CONFIG_CPP11_NULLPTR
+#endif
+#if defined(CLARA_INTERNAL_CONFIG_CPP11_NOEXCEPT) && !defined(CLARA_CONFIG_CPP11_NO_NOEXCEPT) && !defined(CLARA_CONFIG_CPP11_NOEXCEPT) && !defined(CLARA_CONFIG_NO_CPP11)
+#define CLARA_CONFIG_CPP11_NOEXCEPT
+#endif
+#if defined(CLARA_INTERNAL_CONFIG_CPP11_GENERATED_METHODS) && !defined(CLARA_CONFIG_CPP11_NO_GENERATED_METHODS) && !defined(CLARA_CONFIG_CPP11_GENERATED_METHODS) && !defined(CLARA_CONFIG_NO_CPP11)
+#define CLARA_CONFIG_CPP11_GENERATED_METHODS
+#endif
+#if defined(CLARA_INTERNAL_CONFIG_CPP11_OVERRIDE) && !defined(CLARA_CONFIG_NO_OVERRIDE) && !defined(CLARA_CONFIG_CPP11_OVERRIDE) && !defined(CLARA_CONFIG_NO_CPP11)
+#define CLARA_CONFIG_CPP11_OVERRIDE
+#endif
+#if defined(CLARA_INTERNAL_CONFIG_CPP11_UNIQUE_PTR) && !defined(CLARA_CONFIG_NO_UNIQUE_PTR) && !defined(CLARA_CONFIG_CPP11_UNIQUE_PTR) && !defined(CLARA_CONFIG_NO_CPP11)
+#define CLARA_CONFIG_CPP11_UNIQUE_PTR
+#endif
+
+// noexcept support:
+#if defined(CLARA_CONFIG_CPP11_NOEXCEPT) && !defined(CLARA_NOEXCEPT)
+#define CLARA_NOEXCEPT noexcept
+# define CLARA_NOEXCEPT_IS(x) noexcept(x)
+#else
+#define CLARA_NOEXCEPT throw()
+# define CLARA_NOEXCEPT_IS(x)
+#endif
+
+// nullptr support
+#ifdef CLARA_CONFIG_CPP11_NULLPTR
+#define CLARA_NULL nullptr
+#else
+#define CLARA_NULL NULL
+#endif
+
+// override support
+#ifdef CLARA_CONFIG_CPP11_OVERRIDE
+#define CLARA_OVERRIDE override
+#else
+#define CLARA_OVERRIDE
+#endif
+
+// unique_ptr support
+#ifdef CLARA_CONFIG_CPP11_UNIQUE_PTR
+# define CLARA_AUTO_PTR( T ) std::unique_ptr<T>
+#else
+# define CLARA_AUTO_PTR( T ) std::auto_ptr<T>
+#endif
+
+#endif // TWOBLUECUBES_CLARA_COMPILERS_H_INCLUDED
+
+// ----------- end of #include from clara_compilers.h -----------
+// ........... back in clara.h
+
+#include <map>
+#include <stdexcept>
+#include <memory>
+
+#if defined(WIN32) || defined(__WIN32__) || defined(_WIN32) || defined(_MSC_VER)
+#define CLARA_PLATFORM_WINDOWS
+#endif
+
+// Use optional outer namespace
+#ifdef STITCH_CLARA_OPEN_NAMESPACE
+STITCH_CLARA_OPEN_NAMESPACE
+#endif
+
+namespace Clara {
+
+ struct UnpositionalTag {};
+
+ extern UnpositionalTag _;
+
+#ifdef CLARA_CONFIG_MAIN
+ UnpositionalTag _;
+#endif
+
+ namespace Detail {
+
+#ifdef CLARA_CONSOLE_WIDTH
+ const unsigned int consoleWidth = CLARA_CONFIG_CONSOLE_WIDTH;
+#else
+ const unsigned int consoleWidth = 80;
+#endif
+
+ using namespace Tbc;
+
+ inline bool startsWith( std::string const& str, std::string const& prefix ) {
+ return str.size() >= prefix.size() && str.substr( 0, prefix.size() ) == prefix;
+ }
+
+ template<typename T> struct RemoveConstRef{ typedef T type; };
+ template<typename T> struct RemoveConstRef<T&>{ typedef T type; };
+ template<typename T> struct RemoveConstRef<T const&>{ typedef T type; };
+ template<typename T> struct RemoveConstRef<T const>{ typedef T type; };
+
+ template<typename T> struct IsBool { static const bool value = false; };
+ template<> struct IsBool<bool> { static const bool value = true; };
+
+ template<typename T>
+ void convertInto( std::string const& _source, T& _dest ) {
+ std::stringstream ss;
+ ss << _source;
+ ss >> _dest;
+ if( ss.fail() )
+ throw std::runtime_error( "Unable to convert " + _source + " to destination type" );
+ }
+ inline void convertInto( std::string const& _source, std::string& _dest ) {
+ _dest = _source;
+ }
+ inline void convertInto( std::string const& _source, bool& _dest ) {
+ std::string sourceLC = _source;
+ std::transform( sourceLC.begin(), sourceLC.end(), sourceLC.begin(), ::tolower );
+ if( sourceLC == "y" || sourceLC == "1" || sourceLC == "true" || sourceLC == "yes" || sourceLC == "on" )
+ _dest = true;
+ else if( sourceLC == "n" || sourceLC == "0" || sourceLC == "false" || sourceLC == "no" || sourceLC == "off" )
+ _dest = false;
+ else
+ throw std::runtime_error( "Expected a boolean value but did not recognise:\n '" + _source + "'" );
+ }
+
+ template<typename ConfigT>
+ struct IArgFunction {
+ virtual ~IArgFunction() {}
+#ifdef CLARA_CONFIG_CPP11_GENERATED_METHODS
+ IArgFunction() = default;
+ IArgFunction( IArgFunction const& ) = default;
+#endif
+ virtual void set( ConfigT& config, std::string const& value ) const = 0;
+ virtual bool takesArg() const = 0;
+ virtual IArgFunction* clone() const = 0;
+ };
+
+ template<typename ConfigT>
+ class BoundArgFunction {
+ public:
+ BoundArgFunction() : functionObj( CLARA_NULL ) {}
+ BoundArgFunction( IArgFunction<ConfigT>* _functionObj ) : functionObj( _functionObj ) {}
+ BoundArgFunction( BoundArgFunction const& other ) : functionObj( other.functionObj ? other.functionObj->clone() : CLARA_NULL ) {}
+ BoundArgFunction& operator = ( BoundArgFunction const& other ) {
+ IArgFunction<ConfigT>* newFunctionObj = other.functionObj ? other.functionObj->clone() : CLARA_NULL;
+ delete functionObj;
+ functionObj = newFunctionObj;
+ return *this;
+ }
+ ~BoundArgFunction() { delete functionObj; }
+
+ void set( ConfigT& config, std::string const& value ) const {
+ functionObj->set( config, value );
+ }
+ bool takesArg() const { return functionObj->takesArg(); }
+
+ bool isSet() const {
+ return functionObj != CLARA_NULL;
+ }
+ private:
+ IArgFunction<ConfigT>* functionObj;
+ };
+
+ template<typename C>
+ struct NullBinder : IArgFunction<C>{
+ virtual void set( C&, std::string const& ) const {}
+ virtual bool takesArg() const { return true; }
+ virtual IArgFunction<C>* clone() const { return new NullBinder( *this ); }
+ };
+
+ template<typename C, typename M>
+ struct BoundDataMember : IArgFunction<C>{
+ BoundDataMember( M C::* _member ) : member( _member ) {}
+ virtual void set( C& p, std::string const& stringValue ) const {
+ convertInto( stringValue, p.*member );
+ }
+ virtual bool takesArg() const { return !IsBool<M>::value; }
+ virtual IArgFunction<C>* clone() const { return new BoundDataMember( *this ); }
+ M C::* member;
+ };
+ template<typename C, typename M>
+ struct BoundUnaryMethod : IArgFunction<C>{
+ BoundUnaryMethod( void (C::*_member)( M ) ) : member( _member ) {}
+ virtual void set( C& p, std::string const& stringValue ) const {
+ typename RemoveConstRef<M>::type value;
+ convertInto( stringValue, value );
+ (p.*member)( value );
+ }
+ virtual bool takesArg() const { return !IsBool<M>::value; }
+ virtual IArgFunction<C>* clone() const { return new BoundUnaryMethod( *this ); }
+ void (C::*member)( M );
+ };
+ template<typename C>
+ struct BoundNullaryMethod : IArgFunction<C>{
+ BoundNullaryMethod( void (C::*_member)() ) : member( _member ) {}
+ virtual void set( C& p, std::string const& stringValue ) const {
+ bool value;
+ convertInto( stringValue, value );
+ if( value )
+ (p.*member)();
+ }
+ virtual bool takesArg() const { return false; }
+ virtual IArgFunction<C>* clone() const { return new BoundNullaryMethod( *this ); }
+ void (C::*member)();
+ };
+
+ template<typename C>
+ struct BoundUnaryFunction : IArgFunction<C>{
+ BoundUnaryFunction( void (*_function)( C& ) ) : function( _function ) {}
+ virtual void set( C& obj, std::string const& stringValue ) const {
+ bool value;
+ convertInto( stringValue, value );
+ if( value )
+ function( obj );
+ }
+ virtual bool takesArg() const { return false; }
+ virtual IArgFunction<C>* clone() const { return new BoundUnaryFunction( *this ); }
+ void (*function)( C& );
+ };
+
+ template<typename C, typename T>
+ struct BoundBinaryFunction : IArgFunction<C>{
+ BoundBinaryFunction( void (*_function)( C&, T ) ) : function( _function ) {}
+ virtual void set( C& obj, std::string const& stringValue ) const {
+ typename RemoveConstRef<T>::type value;
+ convertInto( stringValue, value );
+ function( obj, value );
+ }
+ virtual bool takesArg() const { return !IsBool<T>::value; }
+ virtual IArgFunction<C>* clone() const { return new BoundBinaryFunction( *this ); }
+ void (*function)( C&, T );
+ };
+
+ } // namespace Detail
+
+ inline std::vector<std::string> argsToVector( int argc, char const* const* const argv ) {
+ std::vector<std::string> args( static_cast<std::size_t>( argc ) );
+ for( std::size_t i = 0; i < static_cast<std::size_t>( argc ); ++i )
+ args[i] = argv[i];
+
+ return args;
+ }
+
+ class Parser {
+ enum Mode { None, MaybeShortOpt, SlashOpt, ShortOpt, LongOpt, Positional };
+ Mode mode;
+ std::size_t from;
+ bool inQuotes;
+ public:
+
+ struct Token {
+ enum Type { Positional, ShortOpt, LongOpt };
+ Token( Type _type, std::string const& _data ) : type( _type ), data( _data ) {}
+ Type type;
+ std::string data;
+ };
+
+ Parser() : mode( None ), from( 0 ), inQuotes( false ){}
+
+ void parseIntoTokens( std::vector<std::string> const& args, std::vector<Token>& tokens ) {
+ const std::string doubleDash = "--";
+ for( std::size_t i = 1; i < args.size() && args[i] != doubleDash; ++i )
+ parseIntoTokens( args[i], tokens);
+ }
+
+ void parseIntoTokens( std::string const& arg, std::vector<Token>& tokens ) {
+ for( std::size_t i = 0; i <= arg.size(); ++i ) {
+ char c = arg[i];
+ if( c == '"' )
+ inQuotes = !inQuotes;
+ mode = handleMode( i, c, arg, tokens );
+ }
+ }
+ Mode handleMode( std::size_t i, char c, std::string const& arg, std::vector<Token>& tokens ) {
+ switch( mode ) {
+ case None: return handleNone( i, c );
+ case MaybeShortOpt: return handleMaybeShortOpt( i, c );
+ case ShortOpt:
+ case LongOpt:
+ case SlashOpt: return handleOpt( i, c, arg, tokens );
+ case Positional: return handlePositional( i, c, arg, tokens );
+ default: throw std::logic_error( "Unknown mode" );
+ }
+ }
+
+ Mode handleNone( std::size_t i, char c ) {
+ if( inQuotes ) {
+ from = i;
+ return Positional;
+ }
+ switch( c ) {
+ case '-': return MaybeShortOpt;
+#ifdef CLARA_PLATFORM_WINDOWS
+ case '/': from = i+1; return SlashOpt;
+#endif
+ default: from = i; return Positional;
+ }
+ }
+ Mode handleMaybeShortOpt( std::size_t i, char c ) {
+ switch( c ) {
+ case '-': from = i+1; return LongOpt;
+ default: from = i; return ShortOpt;
+ }
+ }
+ Mode handleOpt( std::size_t i, char c, std::string const& arg, std::vector<Token>& tokens ) {
+ if( std::string( ":=\0", 5 ).find( c ) == std::string::npos )
+ return mode;
+
+ std::string optName = arg.substr( from, i-from );
+ if( mode == ShortOpt )
+ for( std::size_t j = 0; j < optName.size(); ++j )
+ tokens.push_back( Token( Token::ShortOpt, optName.substr( j, 1 ) ) );
+ else if( mode == SlashOpt && optName.size() == 1 )
+ tokens.push_back( Token( Token::ShortOpt, optName ) );
+ else
+ tokens.push_back( Token( Token::LongOpt, optName ) );
+ return None;
+ }
+ Mode handlePositional( std::size_t i, char c, std::string const& arg, std::vector<Token>& tokens ) {
+ if( inQuotes || std::string( "\0", 3 ).find( c ) == std::string::npos )
+ return mode;
+
+ std::string data = arg.substr( from, i-from );
+ tokens.push_back( Token( Token::Positional, data ) );
+ return None;
+ }
+ };
+
+ template<typename ConfigT>
+ struct CommonArgProperties {
+ CommonArgProperties() {}
+ CommonArgProperties( Detail::BoundArgFunction<ConfigT> const& _boundField ) : boundField( _boundField ) {}
+
+ Detail::BoundArgFunction<ConfigT> boundField;
+ std::string description;
+ std::string detail;
+ std::string placeholder; // Only value if boundField takes an arg
+
+ bool takesArg() const {
+ return !placeholder.empty();
+ }
+ void validate() const {
+ if( !boundField.isSet() )
+ throw std::logic_error( "option not bound" );
+ }
+ };
+ struct OptionArgProperties {
+ std::vector<std::string> shortNames;
+ std::string longName;
+
+ bool hasShortName( std::string const& shortName ) const {
+ return std::find( shortNames.begin(), shortNames.end(), shortName ) != shortNames.end();
+ }
+ bool hasLongName( std::string const& _longName ) const {
+ return _longName == longName;
+ }
+ };
+ struct PositionalArgProperties {
+ PositionalArgProperties() : position( -1 ) {}
+ int position; // -1 means non-positional (floating)
+
+ bool isFixedPositional() const {
+ return position != -1;
+ }
+ };
+
+ template<typename ConfigT>
+ class CommandLine {
+
+ struct Arg : CommonArgProperties<ConfigT>, OptionArgProperties, PositionalArgProperties {
+ Arg() {}
+ Arg( Detail::BoundArgFunction<ConfigT> const& _boundField ) : CommonArgProperties<ConfigT>( _boundField ) {}
+
+ using CommonArgProperties<ConfigT>::placeholder; // !TBD
+
+ std::string dbgName() const {
+ if( !longName.empty() )
+ return "--" + longName;
+ if( !shortNames.empty() )
+ return "-" + shortNames[0];
+ return "positional args";
+ }
+ std::string commands() const {
+ std::ostringstream oss;
+ bool first = true;
+ std::vector<std::string>::const_iterator it = shortNames.begin(), itEnd = shortNames.end();
+ for(; it != itEnd; ++it ) {
+ if( first )
+ first = false;
+ else
+ oss << ", ";
+ oss << "-" << *it;
+ }
+ if( !longName.empty() ) {
+ if( !first )
+ oss << ", ";
+ oss << "--" << longName;
+ }
+ if( !placeholder.empty() )
+ oss << " <" << placeholder << ">";
+ return oss.str();
+ }
+ };
+
+ typedef CLARA_AUTO_PTR( Arg ) ArgAutoPtr;
+
+ friend void addOptName( Arg& arg, std::string const& optName )
+ {
+ if( optName.empty() )
+ return;
+ if( Detail::startsWith( optName, "--" ) ) {
+ if( !arg.longName.empty() )
+ throw std::logic_error( "Only one long opt may be specified. '"
+ + arg.longName
+ + "' already specified, now attempting to add '"
+ + optName + "'" );
+ arg.longName = optName.substr( 2 );
+ }
+ else if( Detail::startsWith( optName, "-" ) )
+ arg.shortNames.push_back( optName.substr( 1 ) );
+ else
+ throw std::logic_error( "option must begin with - or --. Option was: '" + optName + "'" );
+ }
+ friend void setPositionalArg( Arg& arg, int position )
+ {
+ arg.position = position;
+ }
+
+ class ArgBuilder {
+ public:
+ ArgBuilder( Arg* arg ) : m_arg( arg ) {}
+
+ // Bind a non-boolean data member (requires placeholder string)
+ template<typename C, typename M>
+ void bind( M C::* field, std::string const& placeholder ) {
+ m_arg->boundField = new Detail::BoundDataMember<C,M>( field );
+ m_arg->placeholder = placeholder;
+ }
+ // Bind a boolean data member (no placeholder required)
+ template<typename C>
+ void bind( bool C::* field ) {
+ m_arg->boundField = new Detail::BoundDataMember<C,bool>( field );
+ }
+
+ // Bind a method taking a single, non-boolean argument (requires a placeholder string)
+ template<typename C, typename M>
+ void bind( void (C::* unaryMethod)( M ), std::string const& placeholder ) {
+ m_arg->boundField = new Detail::BoundUnaryMethod<C,M>( unaryMethod );
+ m_arg->placeholder = placeholder;
+ }
+
+ // Bind a method taking a single, boolean argument (no placeholder string required)
+ template<typename C>
+ void bind( void (C::* unaryMethod)( bool ) ) {
+ m_arg->boundField = new Detail::BoundUnaryMethod<C,bool>( unaryMethod );
+ }
+
+ // Bind a method that takes no arguments (will be called if opt is present)
+ template<typename C>
+ void bind( void (C::* nullaryMethod)() ) {
+ m_arg->boundField = new Detail::BoundNullaryMethod<C>( nullaryMethod );
+ }
+
+ // Bind a free function taking a single argument - the object to operate on (no placeholder string required)
+ template<typename C>
+ void bind( void (* unaryFunction)( C& ) ) {
+ m_arg->boundField = new Detail::BoundUnaryFunction<C>( unaryFunction );
+ }
+
+ // Bind a free function taking a single argument - the object to operate on (requires a placeholder string)
+ template<typename C, typename T>
+ void bind( void (* binaryFunction)( C&, T ), std::string const& placeholder ) {
+ m_arg->boundField = new Detail::BoundBinaryFunction<C, T>( binaryFunction );
+ m_arg->placeholder = placeholder;
+ }
+
+ ArgBuilder& describe( std::string const& description ) {
+ m_arg->description = description;
+ return *this;
+ }
+ ArgBuilder& detail( std::string const& detail ) {
+ m_arg->detail = detail;
+ return *this;
+ }
+
+ protected:
+ Arg* m_arg;
+ };
+
+ class OptBuilder : public ArgBuilder {
+ public:
+ OptBuilder( Arg* arg ) : ArgBuilder( arg ) {}
+ OptBuilder( OptBuilder& other ) : ArgBuilder( other ) {}
+
+ OptBuilder& operator[]( std::string const& optName ) {
+ addOptName( *ArgBuilder::m_arg, optName );
+ return *this;
+ }
+ };
+
+ public:
+
+ CommandLine()
+ : m_boundProcessName( new Detail::NullBinder<ConfigT>() ),
+ m_highestSpecifiedArgPosition( 0 ),
+ m_throwOnUnrecognisedTokens( false )
+ {}
+ CommandLine( CommandLine const& other )
+ : m_boundProcessName( other.m_boundProcessName ),
+ m_options ( other.m_options ),
+ m_positionalArgs( other.m_positionalArgs ),
+ m_highestSpecifiedArgPosition( other.m_highestSpecifiedArgPosition ),
+ m_throwOnUnrecognisedTokens( other.m_throwOnUnrecognisedTokens )
+ {
+ if( other.m_floatingArg.get() )
+ m_floatingArg.reset( new Arg( *other.m_floatingArg ) );
+ }
+
+ CommandLine& setThrowOnUnrecognisedTokens( bool shouldThrow = true ) {
+ m_throwOnUnrecognisedTokens = shouldThrow;
+ return *this;
+ }
+
+ OptBuilder operator[]( std::string const& optName ) {
+ m_options.push_back( Arg() );
+ addOptName( m_options.back(), optName );
+ OptBuilder builder( &m_options.back() );
+ return builder;
+ }
+
+ ArgBuilder operator[]( int position ) {
+ m_positionalArgs.insert( std::make_pair( position, Arg() ) );
+ if( position > m_highestSpecifiedArgPosition )
+ m_highestSpecifiedArgPosition = position;
+ setPositionalArg( m_positionalArgs[position], position );
+ ArgBuilder builder( &m_positionalArgs[position] );
+ return builder;
+ }
+
+ // Invoke this with the _ instance
+ ArgBuilder operator[]( UnpositionalTag ) {
+ if( m_floatingArg.get() )
+ throw std::logic_error( "Only one unpositional argument can be added" );
+ m_floatingArg.reset( new Arg() );
+ ArgBuilder builder( m_floatingArg.get() );
+ return builder;
+ }
+
+ template<typename C, typename M>
+ void bindProcessName( M C::* field ) {
+ m_boundProcessName = new Detail::BoundDataMember<C,M>( field );
+ }
+ template<typename C, typename M>
+ void bindProcessName( void (C::*_unaryMethod)( M ) ) {
+ m_boundProcessName = new Detail::BoundUnaryMethod<C,M>( _unaryMethod );
+ }
+
+ void optUsage( std::ostream& os, std::size_t indent = 0, std::size_t width = Detail::consoleWidth ) const {
+ typename std::vector<Arg>::const_iterator itBegin = m_options.begin(), itEnd = m_options.end(), it;
+ std::size_t maxWidth = 0;
+ for( it = itBegin; it != itEnd; ++it )
+ maxWidth = (std::max)( maxWidth, it->commands().size() );
+
+ for( it = itBegin; it != itEnd; ++it ) {
+ Detail::Text usage( it->commands(), Detail::TextAttributes()
+ .setWidth( maxWidth+indent )
+ .setIndent( indent ) );
+ Detail::Text desc( it->description, Detail::TextAttributes()
+ .setWidth( width - maxWidth - 3 ) );
+
+ for( std::size_t i = 0; i < (std::max)( usage.size(), desc.size() ); ++i ) {
+ std::string usageCol = i < usage.size() ? usage[i] : "";
+ os << usageCol;
+
+ if( i < desc.size() && !desc[i].empty() )
+ os << std::string( indent + 2 + maxWidth - usageCol.size(), ' ' )
+ << desc[i];
+ os << "\n";
+ }
+ }
+ }
+ std::string optUsage() const {
+ std::ostringstream oss;
+ optUsage( oss );
+ return oss.str();
+ }
+
+ void argSynopsis( std::ostream& os ) const {
+ for( int i = 1; i <= m_highestSpecifiedArgPosition; ++i ) {
+ if( i > 1 )
+ os << " ";
+ typename std::map<int, Arg>::const_iterator it = m_positionalArgs.find( i );
+ if( it != m_positionalArgs.end() )
+ os << "<" << it->second.placeholder << ">";
+ else if( m_floatingArg.get() )
+ os << "<" << m_floatingArg->placeholder << ">";
+ else
+ throw std::logic_error( "non consecutive positional arguments with no floating args" );
+ }
+ // !TBD No indication of mandatory args
+ if( m_floatingArg.get() ) {
+ if( m_highestSpecifiedArgPosition > 1 )
+ os << " ";
+ os << "[<" << m_floatingArg->placeholder << "> ...]";
+ }
+ }
+ std::string argSynopsis() const {
+ std::ostringstream oss;
+ argSynopsis( oss );
+ return oss.str();
+ }
+
+ void usage( std::ostream& os, std::string const& procName ) const {
+ validate();
+ os << "usage:\n " << procName << " ";
+ argSynopsis( os );
+ if( !m_options.empty() ) {
+ os << " [options]\n\nwhere options are: \n";
+ optUsage( os, 2 );
+ }
+ os << "\n";
+ }
+ std::string usage( std::string const& procName ) const {
+ std::ostringstream oss;
+ usage( oss, procName );
+ return oss.str();
+ }
+
+ ConfigT parse( std::vector<std::string> const& args ) const {
+ ConfigT config;
+ parseInto( args, config );
+ return config;
+ }
+
+ std::vector<Parser::Token> parseInto( std::vector<std::string> const& args, ConfigT& config ) const {
+ std::string processName = args[0];
+ std::size_t lastSlash = processName.find_last_of( "/\\" );
+ if( lastSlash != std::string::npos )
+ processName = processName.substr( lastSlash+1 );
+ m_boundProcessName.set( config, processName );
+ std::vector<Parser::Token> tokens;
+ Parser parser;
+ parser.parseIntoTokens( args, tokens );
+ return populate( tokens, config );
+ }
+
+ std::vector<Parser::Token> populate( std::vector<Parser::Token> const& tokens, ConfigT& config ) const {
+ validate();
+ std::vector<Parser::Token> unusedTokens = populateOptions( tokens, config );
+ unusedTokens = populateFixedArgs( unusedTokens, config );
+ unusedTokens = populateFloatingArgs( unusedTokens, config );
+ return unusedTokens;
+ }
+
+ std::vector<Parser::Token> populateOptions( std::vector<Parser::Token> const& tokens, ConfigT& config ) const {
+ std::vector<Parser::Token> unusedTokens;
+ std::vector<std::string> errors;
+ for( std::size_t i = 0; i < tokens.size(); ++i ) {
+ Parser::Token const& token = tokens[i];
+ typename std::vector<Arg>::const_iterator it = m_options.begin(), itEnd = m_options.end();
+ for(; it != itEnd; ++it ) {
+ Arg const& arg = *it;
+
+ try {
+ if( ( token.type == Parser::Token::ShortOpt && arg.hasShortName( token.data ) ) ||
+ ( token.type == Parser::Token::LongOpt && arg.hasLongName( token.data ) ) ) {
+ if( arg.takesArg() ) {
+ if( i == tokens.size()-1 || tokens[i+1].type != Parser::Token::Positional )
+ errors.push_back( "Expected argument to option: " + token.data );
+ else
+ arg.boundField.set( config, tokens[++i].data );
+ }
+ else {
+ arg.boundField.set( config, "true" );
+ }
+ break;
+ }
+ }
+ catch( std::exception& ex ) {
+ errors.push_back( std::string( ex.what() ) + "\n- while parsing: (" + arg.commands() + ")" );
+ }
+ }
+ if( it == itEnd ) {
+ if( token.type == Parser::Token::Positional || !m_throwOnUnrecognisedTokens )
+ unusedTokens.push_back( token );
+ else if( errors.empty() && m_throwOnUnrecognisedTokens )
+ errors.push_back( "unrecognised option: " + token.data );
+ }
+ }
+ if( !errors.empty() ) {
+ std::ostringstream oss;
+ for( std::vector<std::string>::const_iterator it = errors.begin(), itEnd = errors.end();
+ it != itEnd;
+ ++it ) {
+ if( it != errors.begin() )
+ oss << "\n";
+ oss << *it;
+ }
+ throw std::runtime_error( oss.str() );
+ }
+ return unusedTokens;
+ }
+ std::vector<Parser::Token> populateFixedArgs( std::vector<Parser::Token> const& tokens, ConfigT& config ) const {
+ std::vector<Parser::Token> unusedTokens;
+ int position = 1;
+ for( std::size_t i = 0; i < tokens.size(); ++i ) {
+ Parser::Token const& token = tokens[i];
+ typename std::map<int, Arg>::const_iterator it = m_positionalArgs.find( position );
+ if( it != m_positionalArgs.end() )
+ it->second.boundField.set( config, token.data );
+ else
+ unusedTokens.push_back( token );
+ if( token.type == Parser::Token::Positional )
+ position++;
+ }
+ return unusedTokens;
+ }
+ std::vector<Parser::Token> populateFloatingArgs( std::vector<Parser::Token> const& tokens, ConfigT& config ) const {
+ if( !m_floatingArg.get() )
+ return tokens;
+ std::vector<Parser::Token> unusedTokens;
+ for( std::size_t i = 0; i < tokens.size(); ++i ) {
+ Parser::Token const& token = tokens[i];
+ if( token.type == Parser::Token::Positional )
+ m_floatingArg->boundField.set( config, token.data );
+ else
+ unusedTokens.push_back( token );
+ }
+ return unusedTokens;
+ }
+
+ void validate() const
+ {
+ if( m_options.empty() && m_positionalArgs.empty() && !m_floatingArg.get() )
+ throw std::logic_error( "No options or arguments specified" );
+
+ for( typename std::vector<Arg>::const_iterator it = m_options.begin(),
+ itEnd = m_options.end();
+ it != itEnd; ++it )
+ it->validate();
+ }
+
+ private:
+ Detail::BoundArgFunction<ConfigT> m_boundProcessName;
+ std::vector<Arg> m_options;
+ std::map<int, Arg> m_positionalArgs;
+ ArgAutoPtr m_floatingArg;
+ int m_highestSpecifiedArgPosition;
+ bool m_throwOnUnrecognisedTokens;
+ };
+
+} // end namespace Clara
+
+STITCH_CLARA_CLOSE_NAMESPACE
+#undef STITCH_CLARA_OPEN_NAMESPACE
+#undef STITCH_CLARA_CLOSE_NAMESPACE
+
+#endif // TWOBLUECUBES_CLARA_H_INCLUDED
+#undef STITCH_CLARA_OPEN_NAMESPACE
+
+// Restore Clara's value for console width, if present
+#ifdef CATCH_TEMP_CLARA_CONFIG_CONSOLE_WIDTH
+#define CLARA_CONFIG_CONSOLE_WIDTH CATCH_TEMP_CLARA_CONFIG_CONSOLE_WIDTH
+#undef CATCH_TEMP_CLARA_CONFIG_CONSOLE_WIDTH
+#endif
+
+#include <fstream>
+
+namespace Catch {
+
+ inline void abortAfterFirst( ConfigData& config ) { config.abortAfter = 1; }
+ inline void abortAfterX( ConfigData& config, int x ) {
+ if( x < 1 )
+ throw std::runtime_error( "Value after -x or --abortAfter must be greater than zero" );
+ config.abortAfter = x;
+ }
+ inline void addTestOrTags( ConfigData& config, std::string const& _testSpec ) { config.testsOrTags.push_back( _testSpec ); }
+ inline void addReporterName( ConfigData& config, std::string const& _reporterName ) { config.reporterNames.push_back( _reporterName ); }
+
+ inline void addWarning( ConfigData& config, std::string const& _warning ) {
+ if( _warning == "NoAssertions" )
+ config.warnings = static_cast<WarnAbout::What>( config.warnings | WarnAbout::NoAssertions );
+ else
+ throw std::runtime_error( "Unrecognised warning: '" + _warning + "'" );
+ }
+ inline void setOrder( ConfigData& config, std::string const& order ) {
+ if( startsWith( "declared", order ) )
+ config.runOrder = RunTests::InDeclarationOrder;
+ else if( startsWith( "lexical", order ) )
+ config.runOrder = RunTests::InLexicographicalOrder;
+ else if( startsWith( "random", order ) )
+ config.runOrder = RunTests::InRandomOrder;
+ else
+ throw std::runtime_error( "Unrecognised ordering: '" + order + "'" );
+ }
+ inline void setRngSeed( ConfigData& config, std::string const& seed ) {
+ if( seed == "time" ) {
+ config.rngSeed = static_cast<unsigned int>( std::time(0) );
+ }
+ else {
+ std::stringstream ss;
+ ss << seed;
+ ss >> config.rngSeed;
+ if( ss.fail() )
+ throw std::runtime_error( "Argment to --rng-seed should be the word 'time' or a number" );
+ }
+ }
+ inline void setVerbosity( ConfigData& config, int level ) {
+ // !TBD: accept strings?
+ config.verbosity = static_cast<Verbosity::Level>( level );
+ }
+ inline void setShowDurations( ConfigData& config, bool _showDurations ) {
+ config.showDurations = _showDurations
+ ? ShowDurations::Always
+ : ShowDurations::Never;
+ }
+ inline void setUseColour( ConfigData& config, std::string const& value ) {
+ std::string mode = toLower( value );
+
+ if( mode == "yes" )
+ config.useColour = UseColour::Yes;
+ else if( mode == "no" )
+ config.useColour = UseColour::No;
+ else if( mode == "auto" )
+ config.useColour = UseColour::Auto;
+ else
+ throw std::runtime_error( "colour mode must be one of: auto, yes or no" );
+ }
+ inline void forceColour( ConfigData& config ) {
+ config.useColour = UseColour::Yes;
+ }
+ inline void loadTestNamesFromFile( ConfigData& config, std::string const& _filename ) {
+ std::ifstream f( _filename.c_str() );
+ if( !f.is_open() )
+ throw std::domain_error( "Unable to load input file: " + _filename );
+
+ std::string line;
+ while( std::getline( f, line ) ) {
+ line = trim(line);
+ if( !line.empty() && !startsWith( line, "#" ) )
+ addTestOrTags( config, "\"" + line + "\"," );
+ }
+ }
+
+ inline Clara::CommandLine<ConfigData> makeCommandLineParser() {
+
+ using namespace Clara;
+ CommandLine<ConfigData> cli;
+
+ cli.bindProcessName( &ConfigData::processName );
+
+ cli["-?"]["-h"]["--help"]
+ .describe( "display usage information" )
+ .bind( &ConfigData::showHelp );
+
+ cli["-l"]["--list-tests"]
+ .describe( "list all/matching test cases" )
+ .bind( &ConfigData::listTests );
+
+ cli["-t"]["--list-tags"]
+ .describe( "list all/matching tags" )
+ .bind( &ConfigData::listTags );
+
+ cli["-s"]["--success"]
+ .describe( "include successful tests in output" )
+ .bind( &ConfigData::showSuccessfulTests );
+
+ cli["-b"]["--break"]
+ .describe( "break into debugger on failure" )
+ .bind( &ConfigData::shouldDebugBreak );
+
+ cli["-e"]["--nothrow"]
+ .describe( "skip exception tests" )
+ .bind( &ConfigData::noThrow );
+
+ cli["-i"]["--invisibles"]
+ .describe( "show invisibles (tabs, newlines)" )
+ .bind( &ConfigData::showInvisibles );
+
+ cli["-o"]["--out"]
+ .describe( "output filename" )
+ .bind( &ConfigData::outputFilename, "filename" );
+
+ cli["-r"]["--reporter"]
+// .placeholder( "name[:filename]" )
+ .describe( "reporter to use (defaults to console)" )
+ .bind( &addReporterName, "name" );
+
+ cli["-n"]["--name"]
+ .describe( "suite name" )
+ .bind( &ConfigData::name, "name" );
+
+ cli["-a"]["--abort"]
+ .describe( "abort at first failure" )
+ .bind( &abortAfterFirst );
+
+ cli["-x"]["--abortx"]
+ .describe( "abort after x failures" )
+ .bind( &abortAfterX, "no. failures" );
+
+ cli["-w"]["--warn"]
+ .describe( "enable warnings" )
+ .bind( &addWarning, "warning name" );
+
+// - needs updating if reinstated
+// cli.into( &setVerbosity )
+// .describe( "level of verbosity (0=no output)" )
+// .shortOpt( "v")
+// .longOpt( "verbosity" )
+// .placeholder( "level" );
+
+ cli[_]
+ .describe( "which test or tests to use" )
+ .bind( &addTestOrTags, "test name, pattern or tags" );
+
+ cli["-d"]["--durations"]
+ .describe( "show test durations" )
+ .bind( &setShowDurations, "yes|no" );
+
+ cli["-f"]["--input-file"]
+ .describe( "load test names to run from a file" )
+ .bind( &loadTestNamesFromFile, "filename" );
+
+ cli["-#"]["--filenames-as-tags"]
+ .describe( "adds a tag for the filename" )
+ .bind( &ConfigData::filenamesAsTags );
+
+ // Less common commands which don't have a short form
+ cli["--list-test-names-only"]
+ .describe( "list all/matching test cases names only" )
+ .bind( &ConfigData::listTestNamesOnly );
+
+ cli["--list-reporters"]
+ .describe( "list all reporters" )
+ .bind( &ConfigData::listReporters );
+
+ cli["--order"]
+ .describe( "test case order (defaults to decl)" )
+ .bind( &setOrder, "decl|lex|rand" );
+
+ cli["--rng-seed"]
+ .describe( "set a specific seed for random numbers" )
+ .bind( &setRngSeed, "'time'|number" );
+
+ cli["--force-colour"]
+ .describe( "force colourised output (deprecated)" )
+ .bind( &forceColour );
+
+ cli["--use-colour"]
+ .describe( "should output be colourised" )
+ .bind( &setUseColour, "yes|no" );
+
+ return cli;
+ }
+
+} // end namespace Catch
+
+// #included from: internal/catch_list.hpp
+#define TWOBLUECUBES_CATCH_LIST_HPP_INCLUDED
+
+// #included from: catch_text.h
+#define TWOBLUECUBES_CATCH_TEXT_H_INCLUDED
+
+#define TBC_TEXT_FORMAT_CONSOLE_WIDTH CATCH_CONFIG_CONSOLE_WIDTH
+
+#define CLICHE_TBC_TEXT_FORMAT_OUTER_NAMESPACE Catch
+// #included from: ../external/tbc_text_format.h
+// Only use header guard if we are not using an outer namespace
+#ifndef CLICHE_TBC_TEXT_FORMAT_OUTER_NAMESPACE
+# ifdef TWOBLUECUBES_TEXT_FORMAT_H_INCLUDED
+# ifndef TWOBLUECUBES_TEXT_FORMAT_H_ALREADY_INCLUDED
+# define TWOBLUECUBES_TEXT_FORMAT_H_ALREADY_INCLUDED
+# endif
+# else
+# define TWOBLUECUBES_TEXT_FORMAT_H_INCLUDED
+# endif
+#endif
+#ifndef TWOBLUECUBES_TEXT_FORMAT_H_ALREADY_INCLUDED
+#include <string>
+#include <vector>
+#include <sstream>
+
+// Use optional outer namespace
+#ifdef CLICHE_TBC_TEXT_FORMAT_OUTER_NAMESPACE
+namespace CLICHE_TBC_TEXT_FORMAT_OUTER_NAMESPACE {
+#endif
+
+namespace Tbc {
+
+#ifdef TBC_TEXT_FORMAT_CONSOLE_WIDTH
+ const unsigned int consoleWidth = TBC_TEXT_FORMAT_CONSOLE_WIDTH;
+#else
+ const unsigned int consoleWidth = 80;
+#endif
+
+ struct TextAttributes {
+ TextAttributes()
+ : initialIndent( std::string::npos ),
+ indent( 0 ),
+ width( consoleWidth-1 ),
+ tabChar( '\t' )
+ {}
+
+ TextAttributes& setInitialIndent( std::size_t _value ) { initialIndent = _value; return *this; }
+ TextAttributes& setIndent( std::size_t _value ) { indent = _value; return *this; }
+ TextAttributes& setWidth( std::size_t _value ) { width = _value; return *this; }
+ TextAttributes& setTabChar( char _value ) { tabChar = _value; return *this; }
+
+ std::size_t initialIndent; // indent of first line, or npos
+ std::size_t indent; // indent of subsequent lines, or all if initialIndent is npos
+ std::size_t width; // maximum width of text, including indent. Longer text will wrap
+ char tabChar; // If this char is seen the indent is changed to current pos
+ };
+
+ class Text {
+ public:
+ Text( std::string const& _str, TextAttributes const& _attr = TextAttributes() )
+ : attr( _attr )
+ {
+ std::string wrappableChars = " [({.,/|\\-";
+ std::size_t indent = _attr.initialIndent != std::string::npos
+ ? _attr.initialIndent
+ : _attr.indent;
+ std::string remainder = _str;
+
+ while( !remainder.empty() ) {
+ if( lines.size() >= 1000 ) {
+ lines.push_back( "... message truncated due to excessive size" );
+ return;
+ }
+ std::size_t tabPos = std::string::npos;
+ std::size_t width = (std::min)( remainder.size(), _attr.width - indent );
+ std::size_t pos = remainder.find_first_of( '\n' );
+ if( pos <= width ) {
+ width = pos;
+ }
+ pos = remainder.find_last_of( _attr.tabChar, width );
+ if( pos != std::string::npos ) {
+ tabPos = pos;
+ if( remainder[width] == '\n' )
+ width--;
+ remainder = remainder.substr( 0, tabPos ) + remainder.substr( tabPos+1 );
+ }
+
+ if( width == remainder.size() ) {
+ spliceLine( indent, remainder, width );
+ }
+ else if( remainder[width] == '\n' ) {
+ spliceLine( indent, remainder, width );
+ if( width <= 1 || remainder.size() != 1 )
+ remainder = remainder.substr( 1 );
+ indent = _attr.indent;
+ }
+ else {
+ pos = remainder.find_last_of( wrappableChars, width );
+ if( pos != std::string::npos && pos > 0 ) {
+ spliceLine( indent, remainder, pos );
+ if( remainder[0] == ' ' )
+ remainder = remainder.substr( 1 );
+ }
+ else {
+ spliceLine( indent, remainder, width-1 );
+ lines.back() += "-";
+ }
+ if( lines.size() == 1 )
+ indent = _attr.indent;
+ if( tabPos != std::string::npos )
+ indent += tabPos;
+ }
+ }
+ }
+
+ void spliceLine( std::size_t _indent, std::string& _remainder, std::size_t _pos ) {
+ lines.push_back( std::string( _indent, ' ' ) + _remainder.substr( 0, _pos ) );
+ _remainder = _remainder.substr( _pos );
+ }
+
+ typedef std::vector<std::string>::const_iterator const_iterator;
+
+ const_iterator begin() const { return lines.begin(); }
+ const_iterator end() const { return lines.end(); }
+ std::string const& last() const { return lines.back(); }
+ std::size_t size() const { return lines.size(); }
+ std::string const& operator[]( std::size_t _index ) const { return lines[_index]; }
+ std::string toString() const {
+ std::ostringstream oss;
+ oss << *this;
+ return oss.str();
+ }
+
+ inline friend std::ostream& operator << ( std::ostream& _stream, Text const& _text ) {
+ for( Text::const_iterator it = _text.begin(), itEnd = _text.end();
+ it != itEnd; ++it ) {
+ if( it != _text.begin() )
+ _stream << "\n";
+ _stream << *it;
+ }
+ return _stream;
+ }
+
+ private:
+ std::string str;
+ TextAttributes attr;
+ std::vector<std::string> lines;
+ };
+
+} // end namespace Tbc
+
+#ifdef CLICHE_TBC_TEXT_FORMAT_OUTER_NAMESPACE
+} // end outer namespace
+#endif
+
+#endif // TWOBLUECUBES_TEXT_FORMAT_H_ALREADY_INCLUDED
+#undef CLICHE_TBC_TEXT_FORMAT_OUTER_NAMESPACE
+
+namespace Catch {
+ using Tbc::Text;
+ using Tbc::TextAttributes;
+}
+
+// #included from: catch_console_colour.hpp
+#define TWOBLUECUBES_CATCH_CONSOLE_COLOUR_HPP_INCLUDED
+
+namespace Catch {
+
+ struct Colour {
+ enum Code {
+ None = 0,
+
+ White,
+ Red,
+ Green,
+ Blue,
+ Cyan,
+ Yellow,
+ Grey,
+
+ Bright = 0x10,
+
+ BrightRed = Bright | Red,
+ BrightGreen = Bright | Green,
+ LightGrey = Bright | Grey,
+ BrightWhite = Bright | White,
+
+ // By intention
+ FileName = LightGrey,
+ Warning = Yellow,
+ ResultError = BrightRed,
+ ResultSuccess = BrightGreen,
+ ResultExpectedFailure = Warning,
+
+ Error = BrightRed,
+ Success = Green,
+
+ OriginalExpression = Cyan,
+ ReconstructedExpression = Yellow,
+
+ SecondaryText = LightGrey,
+ Headers = White
+ };
+
+ // Use constructed object for RAII guard
+ Colour( Code _colourCode );
+ Colour( Colour const& other );
+ ~Colour();
+
+ // Use static method for one-shot changes
+ static void use( Code _colourCode );
+
+ private:
+ bool m_moved;
+ };
+
+ inline std::ostream& operator << ( std::ostream& os, Colour const& ) { return os; }
+
+} // end namespace Catch
+
+// #included from: catch_interfaces_reporter.h
+#define TWOBLUECUBES_CATCH_INTERFACES_REPORTER_H_INCLUDED
+
+#include <string>
+#include <ostream>
+#include <map>
+#include <assert.h>
+
+namespace Catch
+{
+ struct ReporterConfig {
+ explicit ReporterConfig( Ptr<IConfig const> const& _fullConfig )
+ : m_stream( &_fullConfig->stream() ), m_fullConfig( _fullConfig ) {}
+
+ ReporterConfig( Ptr<IConfig const> const& _fullConfig, std::ostream& _stream )
+ : m_stream( &_stream ), m_fullConfig( _fullConfig ) {}
+
+ std::ostream& stream() const { return *m_stream; }
+ Ptr<IConfig const> fullConfig() const { return m_fullConfig; }
+
+ private:
+ std::ostream* m_stream;
+ Ptr<IConfig const> m_fullConfig;
+ };
+
+ struct ReporterPreferences {
+ ReporterPreferences()
+ : shouldRedirectStdOut( false )
+ {}
+
+ bool shouldRedirectStdOut;
+ };
+
+ template<typename T>
+ struct LazyStat : Option<T> {
+ LazyStat() : used( false ) {}
+ LazyStat& operator=( T const& _value ) {
+ Option<T>::operator=( _value );
+ used = false;
+ return *this;
+ }
+ void reset() {
+ Option<T>::reset();
+ used = false;
+ }
+ bool used;
+ };
+
+ struct TestRunInfo {
+ TestRunInfo( std::string const& _name ) : name( _name ) {}
+ std::string name;
+ };
+ struct GroupInfo {
+ GroupInfo( std::string const& _name,
+ std::size_t _groupIndex,
+ std::size_t _groupsCount )
+ : name( _name ),
+ groupIndex( _groupIndex ),
+ groupsCounts( _groupsCount )
+ {}
+
+ std::string name;
+ std::size_t groupIndex;
+ std::size_t groupsCounts;
+ };
+
+ struct AssertionStats {
+ AssertionStats( AssertionResult const& _assertionResult,
+ std::vector<MessageInfo> const& _infoMessages,
+ Totals const& _totals )
+ : assertionResult( _assertionResult ),
+ infoMessages( _infoMessages ),
+ totals( _totals )
+ {
+ if( assertionResult.hasMessage() ) {
+ // Copy message into messages list.
+ // !TBD This should have been done earlier, somewhere
+ MessageBuilder builder( assertionResult.getTestMacroName(), assertionResult.getSourceInfo(), assertionResult.getResultType() );
+ builder << assertionResult.getMessage();
+ builder.m_info.message = builder.m_stream.str();
+
+ infoMessages.push_back( builder.m_info );
+ }
+ }
+ virtual ~AssertionStats();
+
+# ifdef CATCH_CONFIG_CPP11_GENERATED_METHODS
+ AssertionStats( AssertionStats const& ) = default;
+ AssertionStats( AssertionStats && ) = default;
+ AssertionStats& operator = ( AssertionStats const& ) = default;
+ AssertionStats& operator = ( AssertionStats && ) = default;
+# endif
+
+ AssertionResult assertionResult;
+ std::vector<MessageInfo> infoMessages;
+ Totals totals;
+ };
+
+ struct SectionStats {
+ SectionStats( SectionInfo const& _sectionInfo,
+ Counts const& _assertions,
+ double _durationInSeconds,
+ bool _missingAssertions )
+ : sectionInfo( _sectionInfo ),
+ assertions( _assertions ),
+ durationInSeconds( _durationInSeconds ),
+ missingAssertions( _missingAssertions )
+ {}
+ virtual ~SectionStats();
+# ifdef CATCH_CONFIG_CPP11_GENERATED_METHODS
+ SectionStats( SectionStats const& ) = default;
+ SectionStats( SectionStats && ) = default;
+ SectionStats& operator = ( SectionStats const& ) = default;
+ SectionStats& operator = ( SectionStats && ) = default;
+# endif
+
+ SectionInfo sectionInfo;
+ Counts assertions;
+ double durationInSeconds;
+ bool missingAssertions;
+ };
+
+ struct TestCaseStats {
+ TestCaseStats( TestCaseInfo const& _testInfo,
+ Totals const& _totals,
+ std::string const& _stdOut,
+ std::string const& _stdErr,
+ bool _aborting )
+ : testInfo( _testInfo ),
+ totals( _totals ),
+ stdOut( _stdOut ),
+ stdErr( _stdErr ),
+ aborting( _aborting )
+ {}
+ virtual ~TestCaseStats();
+
+# ifdef CATCH_CONFIG_CPP11_GENERATED_METHODS
+ TestCaseStats( TestCaseStats const& ) = default;
+ TestCaseStats( TestCaseStats && ) = default;
+ TestCaseStats& operator = ( TestCaseStats const& ) = default;
+ TestCaseStats& operator = ( TestCaseStats && ) = default;
+# endif
+
+ TestCaseInfo testInfo;
+ Totals totals;
+ std::string stdOut;
+ std::string stdErr;
+ bool aborting;
+ };
+
+ struct TestGroupStats {
+ TestGroupStats( GroupInfo const& _groupInfo,
+ Totals const& _totals,
+ bool _aborting )
+ : groupInfo( _groupInfo ),
+ totals( _totals ),
+ aborting( _aborting )
+ {}
+ TestGroupStats( GroupInfo const& _groupInfo )
+ : groupInfo( _groupInfo ),
+ aborting( false )
+ {}
+ virtual ~TestGroupStats();
+
+# ifdef CATCH_CONFIG_CPP11_GENERATED_METHODS
+ TestGroupStats( TestGroupStats const& ) = default;
+ TestGroupStats( TestGroupStats && ) = default;
+ TestGroupStats& operator = ( TestGroupStats const& ) = default;
+ TestGroupStats& operator = ( TestGroupStats && ) = default;
+# endif
+
+ GroupInfo groupInfo;
+ Totals totals;
+ bool aborting;
+ };
+
+ struct TestRunStats {
+ TestRunStats( TestRunInfo const& _runInfo,
+ Totals const& _totals,
+ bool _aborting )
+ : runInfo( _runInfo ),
+ totals( _totals ),
+ aborting( _aborting )
+ {}
+ virtual ~TestRunStats();
+
+# ifndef CATCH_CONFIG_CPP11_GENERATED_METHODS
+ TestRunStats( TestRunStats const& _other )
+ : runInfo( _other.runInfo ),
+ totals( _other.totals ),
+ aborting( _other.aborting )
+ {}
+# else
+ TestRunStats( TestRunStats const& ) = default;
+ TestRunStats( TestRunStats && ) = default;
+ TestRunStats& operator = ( TestRunStats const& ) = default;
+ TestRunStats& operator = ( TestRunStats && ) = default;
+# endif
+
+ TestRunInfo runInfo;
+ Totals totals;
+ bool aborting;
+ };
+
+ class MultipleReporters;
+
+ struct IStreamingReporter : IShared {
+ virtual ~IStreamingReporter();
+
+ // Implementing class must also provide the following static method:
+ // static std::string getDescription();
+
+ virtual ReporterPreferences getPreferences() const = 0;
+
+ virtual void noMatchingTestCases( std::string const& spec ) = 0;
+
+ virtual void testRunStarting( TestRunInfo const& testRunInfo ) = 0;
+ virtual void testGroupStarting( GroupInfo const& groupInfo ) = 0;
+
+ virtual void testCaseStarting( TestCaseInfo const& testInfo ) = 0;
+ virtual void sectionStarting( SectionInfo const& sectionInfo ) = 0;
+
+ virtual void assertionStarting( AssertionInfo const& assertionInfo ) = 0;
+
+ // The return value indicates if the messages buffer should be cleared:
+ virtual bool assertionEnded( AssertionStats const& assertionStats ) = 0;
+
+ virtual void sectionEnded( SectionStats const& sectionStats ) = 0;
+ virtual void testCaseEnded( TestCaseStats const& testCaseStats ) = 0;
+ virtual void testGroupEnded( TestGroupStats const& testGroupStats ) = 0;
+ virtual void testRunEnded( TestRunStats const& testRunStats ) = 0;
+
+ virtual void skipTest( TestCaseInfo const& testInfo ) = 0;
+
+ virtual MultipleReporters* tryAsMulti() { return CATCH_NULL; }
+ };
+
+ struct IReporterFactory : IShared {
+ virtual ~IReporterFactory();
+ virtual IStreamingReporter* create( ReporterConfig const& config ) const = 0;
+ virtual std::string getDescription() const = 0;
+ };
+
+ struct IReporterRegistry {
+ typedef std::map<std::string, Ptr<IReporterFactory> > FactoryMap;
+ typedef std::vector<Ptr<IReporterFactory> > Listeners;
+
+ virtual ~IReporterRegistry();
+ virtual IStreamingReporter* create( std::string const& name, Ptr<IConfig const> const& config ) const = 0;
+ virtual FactoryMap const& getFactories() const = 0;
+ virtual Listeners const& getListeners() const = 0;
+ };
+
+ Ptr<IStreamingReporter> addReporter( Ptr<IStreamingReporter> const& existingReporter, Ptr<IStreamingReporter> const& additionalReporter );
+
+}
+
+#include <limits>
+#include <algorithm>
+
+namespace Catch {
+
+ inline std::size_t listTests( Config const& config ) {
+
+ TestSpec testSpec = config.testSpec();
+ if( config.testSpec().hasFilters() )
+ Catch::cout() << "Matching test cases:\n";
+ else {
+ Catch::cout() << "All available test cases:\n";
+ testSpec = TestSpecParser( ITagAliasRegistry::get() ).parse( "*" ).testSpec();
+ }
+
+ std::size_t matchedTests = 0;
+ TextAttributes nameAttr, tagsAttr;
+ nameAttr.setInitialIndent( 2 ).setIndent( 4 );
+ tagsAttr.setIndent( 6 );
+
+ std::vector<TestCase> matchedTestCases = filterTests( getAllTestCasesSorted( config ), testSpec, config );
+ for( std::vector<TestCase>::const_iterator it = matchedTestCases.begin(), itEnd = matchedTestCases.end();
+ it != itEnd;
+ ++it ) {
+ matchedTests++;
+ TestCaseInfo const& testCaseInfo = it->getTestCaseInfo();
+ Colour::Code colour = testCaseInfo.isHidden()
+ ? Colour::SecondaryText
+ : Colour::None;
+ Colour colourGuard( colour );
+
+ Catch::cout() << Text( testCaseInfo.name, nameAttr ) << std::endl;
+ if( !testCaseInfo.tags.empty() )
+ Catch::cout() << Text( testCaseInfo.tagsAsString, tagsAttr ) << std::endl;
+ }
+
+ if( !config.testSpec().hasFilters() )
+ Catch::cout() << pluralise( matchedTests, "test case" ) << "\n" << std::endl;
+ else
+ Catch::cout() << pluralise( matchedTests, "matching test case" ) << "\n" << std::endl;
+ return matchedTests;
+ }
+
+ inline std::size_t listTestsNamesOnly( Config const& config ) {
+ TestSpec testSpec = config.testSpec();
+ if( !config.testSpec().hasFilters() )
+ testSpec = TestSpecParser( ITagAliasRegistry::get() ).parse( "*" ).testSpec();
+ std::size_t matchedTests = 0;
+ std::vector<TestCase> matchedTestCases = filterTests( getAllTestCasesSorted( config ), testSpec, config );
+ for( std::vector<TestCase>::const_iterator it = matchedTestCases.begin(), itEnd = matchedTestCases.end();
+ it != itEnd;
+ ++it ) {
+ matchedTests++;
+ TestCaseInfo const& testCaseInfo = it->getTestCaseInfo();
+ Catch::cout() << testCaseInfo.name << std::endl;
+ }
+ return matchedTests;
+ }
+
+ struct TagInfo {
+ TagInfo() : count ( 0 ) {}
+ void add( std::string const& spelling ) {
+ ++count;
+ spellings.insert( spelling );
+ }
+ std::string all() const {
+ std::string out;
+ for( std::set<std::string>::const_iterator it = spellings.begin(), itEnd = spellings.end();
+ it != itEnd;
+ ++it )
+ out += "[" + *it + "]";
+ return out;
+ }
+ std::set<std::string> spellings;
+ std::size_t count;
+ };
+
+ inline std::size_t listTags( Config const& config ) {
+ TestSpec testSpec = config.testSpec();
+ if( config.testSpec().hasFilters() )
+ Catch::cout() << "Tags for matching test cases:\n";
+ else {
+ Catch::cout() << "All available tags:\n";
+ testSpec = TestSpecParser( ITagAliasRegistry::get() ).parse( "*" ).testSpec();
+ }
+
+ std::map<std::string, TagInfo> tagCounts;
+
+ std::vector<TestCase> matchedTestCases = filterTests( getAllTestCasesSorted( config ), testSpec, config );
+ for( std::vector<TestCase>::const_iterator it = matchedTestCases.begin(), itEnd = matchedTestCases.end();
+ it != itEnd;
+ ++it ) {
+ for( std::set<std::string>::const_iterator tagIt = it->getTestCaseInfo().tags.begin(),
+ tagItEnd = it->getTestCaseInfo().tags.end();
+ tagIt != tagItEnd;
+ ++tagIt ) {
+ std::string tagName = *tagIt;
+ std::string lcaseTagName = toLower( tagName );
+ std::map<std::string, TagInfo>::iterator countIt = tagCounts.find( lcaseTagName );
+ if( countIt == tagCounts.end() )
+ countIt = tagCounts.insert( std::make_pair( lcaseTagName, TagInfo() ) ).first;
+ countIt->second.add( tagName );
+ }
+ }
+
+ for( std::map<std::string, TagInfo>::const_iterator countIt = tagCounts.begin(),
+ countItEnd = tagCounts.end();
+ countIt != countItEnd;
+ ++countIt ) {
+ std::ostringstream oss;
+ oss << " " << std::setw(2) << countIt->second.count << " ";
+ Text wrapper( countIt->second.all(), TextAttributes()
+ .setInitialIndent( 0 )
+ .setIndent( oss.str().size() )
+ .setWidth( CATCH_CONFIG_CONSOLE_WIDTH-10 ) );
+ Catch::cout() << oss.str() << wrapper << "\n";
+ }
+ Catch::cout() << pluralise( tagCounts.size(), "tag" ) << "\n" << std::endl;
+ return tagCounts.size();
+ }
+
+ inline std::size_t listReporters( Config const& /*config*/ ) {
+ Catch::cout() << "Available reporters:\n";
+ IReporterRegistry::FactoryMap const& factories = getRegistryHub().getReporterRegistry().getFactories();
+ IReporterRegistry::FactoryMap::const_iterator itBegin = factories.begin(), itEnd = factories.end(), it;
+ std::size_t maxNameLen = 0;
+ for(it = itBegin; it != itEnd; ++it )
+ maxNameLen = (std::max)( maxNameLen, it->first.size() );
+
+ for(it = itBegin; it != itEnd; ++it ) {
+ Text wrapper( it->second->getDescription(), TextAttributes()
+ .setInitialIndent( 0 )
+ .setIndent( 7+maxNameLen )
+ .setWidth( CATCH_CONFIG_CONSOLE_WIDTH - maxNameLen-8 ) );
+ Catch::cout() << " "
+ << it->first
+ << ":"
+ << std::string( maxNameLen - it->first.size() + 2, ' ' )
+ << wrapper << "\n";
+ }
+ Catch::cout() << std::endl;
+ return factories.size();
+ }
+
+ inline Option<std::size_t> list( Config const& config ) {
+ Option<std::size_t> listedCount;
+ if( config.listTests() )
+ listedCount = listedCount.valueOr(0) + listTests( config );
+ if( config.listTestNamesOnly() )
+ listedCount = listedCount.valueOr(0) + listTestsNamesOnly( config );
+ if( config.listTags() )
+ listedCount = listedCount.valueOr(0) + listTags( config );
+ if( config.listReporters() )
+ listedCount = listedCount.valueOr(0) + listReporters( config );
+ return listedCount;
+ }
+
+} // end namespace Catch
+
+// #included from: internal/catch_run_context.hpp
+#define TWOBLUECUBES_CATCH_RUNNER_IMPL_HPP_INCLUDED
+
+// #included from: catch_test_case_tracker.hpp
+#define TWOBLUECUBES_CATCH_TEST_CASE_TRACKER_HPP_INCLUDED
+
+#include <map>
+#include <string>
+#include <assert.h>
+#include <vector>
+
+namespace Catch {
+namespace TestCaseTracking {
+
+ struct ITracker : SharedImpl<> {
+ virtual ~ITracker();
+
+ // static queries
+ virtual std::string name() const = 0;
+
+ // dynamic queries
+ virtual bool isComplete() const = 0; // Successfully completed or failed
+ virtual bool isSuccessfullyCompleted() const = 0;
+ virtual bool isOpen() const = 0; // Started but not complete
+ virtual bool hasChildren() const = 0;
+
+ virtual ITracker& parent() = 0;
+
+ // actions
+ virtual void close() = 0; // Successfully complete
+ virtual void fail() = 0;
+ virtual void markAsNeedingAnotherRun() = 0;
+
+ virtual void addChild( Ptr<ITracker> const& child ) = 0;
+ virtual ITracker* findChild( std::string const& name ) = 0;
+ virtual void openChild() = 0;
+
+ // Debug/ checking
+ virtual bool isSectionTracker() const = 0;
+ virtual bool isIndexTracker() const = 0;
+ };
+
+ class TrackerContext {
+
+ enum RunState {
+ NotStarted,
+ Executing,
+ CompletedCycle
+ };
+
+ Ptr<ITracker> m_rootTracker;
+ ITracker* m_currentTracker;
+ RunState m_runState;
+
+ public:
+
+ static TrackerContext& instance() {
+ static TrackerContext s_instance;
+ return s_instance;
+ }
+
+ TrackerContext()
+ : m_currentTracker( CATCH_NULL ),
+ m_runState( NotStarted )
+ {}
+
+ ITracker& startRun();
+
+ void endRun() {
+ m_rootTracker.reset();
+ m_currentTracker = CATCH_NULL;
+ m_runState = NotStarted;
+ }
+
+ void startCycle() {
+ m_currentTracker = m_rootTracker.get();
+ m_runState = Executing;
+ }
+ void completeCycle() {
+ m_runState = CompletedCycle;
+ }
+
+ bool completedCycle() const {
+ return m_runState == CompletedCycle;
+ }
+ ITracker& currentTracker() {
+ return *m_currentTracker;
+ }
+ void setCurrentTracker( ITracker* tracker ) {
+ m_currentTracker = tracker;
+ }
+ };
+
+ class TrackerBase : public ITracker {
+ protected:
+ enum CycleState {
+ NotStarted,
+ Executing,
+ ExecutingChildren,
+ NeedsAnotherRun,
+ CompletedSuccessfully,
+ Failed
+ };
+ class TrackerHasName {
+ std::string m_name;
+ public:
+ TrackerHasName( std::string const& name ) : m_name( name ) {}
+ bool operator ()( Ptr<ITracker> const& tracker ) {
+ return tracker->name() == m_name;
+ }
+ };
+ typedef std::vector<Ptr<ITracker> > Children;
+ std::string m_name;
+ TrackerContext& m_ctx;
+ ITracker* m_parent;
+ Children m_children;
+ CycleState m_runState;
+ public:
+ TrackerBase( std::string const& name, TrackerContext& ctx, ITracker* parent )
+ : m_name( name ),
+ m_ctx( ctx ),
+ m_parent( parent ),
+ m_runState( NotStarted )
+ {}
+ virtual ~TrackerBase();
+
+ virtual std::string name() const CATCH_OVERRIDE {
+ return m_name;
+ }
+ virtual bool isComplete() const CATCH_OVERRIDE {
+ return m_runState == CompletedSuccessfully || m_runState == Failed;
+ }
+ virtual bool isSuccessfullyCompleted() const CATCH_OVERRIDE {
+ return m_runState == CompletedSuccessfully;
+ }
+ virtual bool isOpen() const CATCH_OVERRIDE {
+ return m_runState != NotStarted && !isComplete();
+ }
+ virtual bool hasChildren() const CATCH_OVERRIDE {
+ return !m_children.empty();
+ }
+
+ virtual void addChild( Ptr<ITracker> const& child ) CATCH_OVERRIDE {
+ m_children.push_back( child );
+ }
+
+ virtual ITracker* findChild( std::string const& name ) CATCH_OVERRIDE {
+ Children::const_iterator it = std::find_if( m_children.begin(), m_children.end(), TrackerHasName( name ) );
+ return( it != m_children.end() )
+ ? it->get()
+ : CATCH_NULL;
+ }
+ virtual ITracker& parent() CATCH_OVERRIDE {
+ assert( m_parent ); // Should always be non-null except for root
+ return *m_parent;
+ }
+
+ virtual void openChild() CATCH_OVERRIDE {
+ if( m_runState != ExecutingChildren ) {
+ m_runState = ExecutingChildren;
+ if( m_parent )
+ m_parent->openChild();
+ }
+ }
+
+ virtual bool isSectionTracker() const CATCH_OVERRIDE { return false; }
+ virtual bool isIndexTracker() const CATCH_OVERRIDE { return false; }
+
+ void open() {
+ m_runState = Executing;
+ moveToThis();
+ if( m_parent )
+ m_parent->openChild();
+ }
+
+ virtual void close() CATCH_OVERRIDE {
+
+ // Close any still open children (e.g. generators)
+ while( &m_ctx.currentTracker() != this )
+ m_ctx.currentTracker().close();
+
+ switch( m_runState ) {
+ case NotStarted:
+ case CompletedSuccessfully:
+ case Failed:
+ throw std::logic_error( "Illogical state" );
+
+ case NeedsAnotherRun:
+ break;;
+
+ case Executing:
+ m_runState = CompletedSuccessfully;
+ break;
+ case ExecutingChildren:
+ if( m_children.empty() || m_children.back()->isComplete() )
+ m_runState = CompletedSuccessfully;
+ break;
+
+ default:
+ throw std::logic_error( "Unexpected state" );
+ }
+ moveToParent();
+ m_ctx.completeCycle();
+ }
+ virtual void fail() CATCH_OVERRIDE {
+ m_runState = Failed;
+ if( m_parent )
+ m_parent->markAsNeedingAnotherRun();
+ moveToParent();
+ m_ctx.completeCycle();
+ }
+ virtual void markAsNeedingAnotherRun() CATCH_OVERRIDE {
+ m_runState = NeedsAnotherRun;
+ }
+ private:
+ void moveToParent() {
+ assert( m_parent );
+ m_ctx.setCurrentTracker( m_parent );
+ }
+ void moveToThis() {
+ m_ctx.setCurrentTracker( this );
+ }
+ };
+
+ class SectionTracker : public TrackerBase {
+ public:
+ SectionTracker( std::string const& name, TrackerContext& ctx, ITracker* parent )
+ : TrackerBase( name, ctx, parent )
+ {}
+ virtual ~SectionTracker();
+
+ virtual bool isSectionTracker() const CATCH_OVERRIDE { return true; }
+
+ static SectionTracker& acquire( TrackerContext& ctx, std::string const& name ) {
+ SectionTracker* section = CATCH_NULL;
+
+ ITracker& currentTracker = ctx.currentTracker();
+ if( ITracker* childTracker = currentTracker.findChild( name ) ) {
+ assert( childTracker );
+ assert( childTracker->isSectionTracker() );
+ section = static_cast<SectionTracker*>( childTracker );
+ }
+ else {
+ section = new SectionTracker( name, ctx, &currentTracker );
+ currentTracker.addChild( section );
+ }
+ if( !ctx.completedCycle() && !section->isComplete() ) {
+
+ section->open();
+ }
+ return *section;
+ }
+ };
+
+ class IndexTracker : public TrackerBase {
+ int m_size;
+ int m_index;
+ public:
+ IndexTracker( std::string const& name, TrackerContext& ctx, ITracker* parent, int size )
+ : TrackerBase( name, ctx, parent ),
+ m_size( size ),
+ m_index( -1 )
+ {}
+ virtual ~IndexTracker();
+
+ virtual bool isIndexTracker() const CATCH_OVERRIDE { return true; }
+
+ static IndexTracker& acquire( TrackerContext& ctx, std::string const& name, int size ) {
+ IndexTracker* tracker = CATCH_NULL;
+
+ ITracker& currentTracker = ctx.currentTracker();
+ if( ITracker* childTracker = currentTracker.findChild( name ) ) {
+ assert( childTracker );
+ assert( childTracker->isIndexTracker() );
+ tracker = static_cast<IndexTracker*>( childTracker );
+ }
+ else {
+ tracker = new IndexTracker( name, ctx, &currentTracker, size );
+ currentTracker.addChild( tracker );
+ }
+
+ if( !ctx.completedCycle() && !tracker->isComplete() ) {
+ if( tracker->m_runState != ExecutingChildren && tracker->m_runState != NeedsAnotherRun )
+ tracker->moveNext();
+ tracker->open();
+ }
+
+ return *tracker;
+ }
+
+ int index() const { return m_index; }
+
+ void moveNext() {
+ m_index++;
+ m_children.clear();
+ }
+
+ virtual void close() CATCH_OVERRIDE {
+ TrackerBase::close();
+ if( m_runState == CompletedSuccessfully && m_index < m_size-1 )
+ m_runState = Executing;
+ }
+ };
+
+ inline ITracker& TrackerContext::startRun() {
+ m_rootTracker = new SectionTracker( "{root}", *this, CATCH_NULL );
+ m_currentTracker = CATCH_NULL;
+ m_runState = Executing;
+ return *m_rootTracker;
+ }
+
+} // namespace TestCaseTracking
+
+using TestCaseTracking::ITracker;
+using TestCaseTracking::TrackerContext;
+using TestCaseTracking::SectionTracker;
+using TestCaseTracking::IndexTracker;
+
+} // namespace Catch
+
+// #included from: catch_fatal_condition.hpp
+#define TWOBLUECUBES_CATCH_FATAL_CONDITION_H_INCLUDED
+
+namespace Catch {
+
+ // Report the error condition then exit the process
+ inline void fatal( std::string const& message, int exitCode ) {
+ IContext& context = Catch::getCurrentContext();
+ IResultCapture* resultCapture = context.getResultCapture();
+ resultCapture->handleFatalErrorCondition( message );
+
+ if( Catch::alwaysTrue() ) // avoids "no return" warnings
+ exit( exitCode );
+ }
+
+} // namespace Catch
+
+#if defined ( CATCH_PLATFORM_WINDOWS ) /////////////////////////////////////////
+
+namespace Catch {
+
+ struct FatalConditionHandler {
+ void reset() {}
+ };
+
+} // namespace Catch
+
+#else // Not Windows - assumed to be POSIX compatible //////////////////////////
+
+#include <signal.h>
+
+namespace Catch {
+
+ struct SignalDefs { int id; const char* name; };
+ extern SignalDefs signalDefs[];
+ SignalDefs signalDefs[] = {
+ { SIGINT, "SIGINT - Terminal interrupt signal" },
+ { SIGILL, "SIGILL - Illegal instruction signal" },
+ { SIGFPE, "SIGFPE - Floating point error signal" },
+ { SIGSEGV, "SIGSEGV - Segmentation violation signal" },
+ { SIGTERM, "SIGTERM - Termination request signal" },
+ { SIGABRT, "SIGABRT - Abort (abnormal termination) signal" }
+ };
+
+ struct FatalConditionHandler {
+
+ static void handleSignal( int sig ) {
+ for( std::size_t i = 0; i < sizeof(signalDefs)/sizeof(SignalDefs); ++i )
+ if( sig == signalDefs[i].id )
+ fatal( signalDefs[i].name, -sig );
+ fatal( "<unknown signal>", -sig );
+ }
+
+ FatalConditionHandler() : m_isSet( true ) {
+ for( std::size_t i = 0; i < sizeof(signalDefs)/sizeof(SignalDefs); ++i )
+ signal( signalDefs[i].id, handleSignal );
+ }
+ ~FatalConditionHandler() {
+ reset();
+ }
+ void reset() {
+ if( m_isSet ) {
+ for( std::size_t i = 0; i < sizeof(signalDefs)/sizeof(SignalDefs); ++i )
+ signal( signalDefs[i].id, SIG_DFL );
+ m_isSet = false;
+ }
+ }
+
+ bool m_isSet;
+ };
+
+} // namespace Catch
+
+#endif // not Windows
+
+#include <set>
+#include <string>
+
+namespace Catch {
+
+ class StreamRedirect {
+
+ public:
+ StreamRedirect( std::ostream& stream, std::string& targetString )
+ : m_stream( stream ),
+ m_prevBuf( stream.rdbuf() ),
+ m_targetString( targetString )
+ {
+ stream.rdbuf( m_oss.rdbuf() );
+ }
+
+ ~StreamRedirect() {
+ m_targetString += m_oss.str();
+ m_stream.rdbuf( m_prevBuf );
+ }
+
+ private:
+ std::ostream& m_stream;
+ std::streambuf* m_prevBuf;
+ std::ostringstream m_oss;
+ std::string& m_targetString;
+ };
+
+ ///////////////////////////////////////////////////////////////////////////
+
+ class RunContext : public IResultCapture, public IRunner {
+
+ RunContext( RunContext const& );
+ void operator =( RunContext const& );
+
+ public:
+
+ explicit RunContext( Ptr<IConfig const> const& _config, Ptr<IStreamingReporter> const& reporter )
+ : m_runInfo( _config->name() ),
+ m_context( getCurrentMutableContext() ),
+ m_activeTestCase( CATCH_NULL ),
+ m_config( _config ),
+ m_reporter( reporter )
+ {
+ m_context.setRunner( this );
+ m_context.setConfig( m_config );
+ m_context.setResultCapture( this );
+ m_reporter->testRunStarting( m_runInfo );
+ }
+
+ virtual ~RunContext() {
+ m_reporter->testRunEnded( TestRunStats( m_runInfo, m_totals, aborting() ) );
+ }
+
+ void testGroupStarting( std::string const& testSpec, std::size_t groupIndex, std::size_t groupsCount ) {
+ m_reporter->testGroupStarting( GroupInfo( testSpec, groupIndex, groupsCount ) );
+ }
+ void testGroupEnded( std::string const& testSpec, Totals const& totals, std::size_t groupIndex, std::size_t groupsCount ) {
+ m_reporter->testGroupEnded( TestGroupStats( GroupInfo( testSpec, groupIndex, groupsCount ), totals, aborting() ) );
+ }
+
+ Totals runTest( TestCase const& testCase ) {
+ Totals prevTotals = m_totals;
+
+ std::string redirectedCout;
+ std::string redirectedCerr;
+
+ TestCaseInfo testInfo = testCase.getTestCaseInfo();
+
+ m_reporter->testCaseStarting( testInfo );
+
+ m_activeTestCase = &testCase;
+
+ do {
+ m_trackerContext.startRun();
+ do {
+ m_trackerContext.startCycle();
+ m_testCaseTracker = &SectionTracker::acquire( m_trackerContext, testInfo.name );
+ runCurrentTest( redirectedCout, redirectedCerr );
+ }
+ while( !m_testCaseTracker->isSuccessfullyCompleted() && !aborting() );
+ }
+ // !TBD: deprecated - this will be replaced by indexed trackers
+ while( getCurrentContext().advanceGeneratorsForCurrentTest() && !aborting() );
+
+ Totals deltaTotals = m_totals.delta( prevTotals );
+ if( testInfo.expectedToFail() && deltaTotals.testCases.passed > 0 ) {
+ deltaTotals.assertions.failed++;
+ deltaTotals.testCases.passed--;
+ deltaTotals.testCases.failed++;
+ }
+ m_totals.testCases += deltaTotals.testCases;
+ m_reporter->testCaseEnded( TestCaseStats( testInfo,
+ deltaTotals,
+ redirectedCout,
+ redirectedCerr,
+ aborting() ) );
+
+ m_activeTestCase = CATCH_NULL;
+ m_testCaseTracker = CATCH_NULL;
+
+ return deltaTotals;
+ }
+
+ Ptr<IConfig const> config() const {
+ return m_config;
+ }
+
+ private: // IResultCapture
+
+ virtual void assertionEnded( AssertionResult const& result ) {
+ if( result.getResultType() == ResultWas::Ok ) {
+ m_totals.assertions.passed++;
+ }
+ else if( !result.isOk() ) {
+ m_totals.assertions.failed++;
+ }
+
+ if( m_reporter->assertionEnded( AssertionStats( result, m_messages, m_totals ) ) )
+ m_messages.clear();
+
+ // Reset working state
+ m_lastAssertionInfo = AssertionInfo( "", m_lastAssertionInfo.lineInfo, "{Unknown expression after the reported line}" , m_lastAssertionInfo.resultDisposition );
+ m_lastResult = result;
+ }
+
+ virtual bool sectionStarted (
+ SectionInfo const& sectionInfo,
+ Counts& assertions
+ )
+ {
+ std::ostringstream oss;
+ oss << sectionInfo.name << "@" << sectionInfo.lineInfo;
+
+ ITracker& sectionTracker = SectionTracker::acquire( m_trackerContext, oss.str() );
+ if( !sectionTracker.isOpen() )
+ return false;
+ m_activeSections.push_back( &sectionTracker );
+
+ m_lastAssertionInfo.lineInfo = sectionInfo.lineInfo;
+
+ m_reporter->sectionStarting( sectionInfo );
+
+ assertions = m_totals.assertions;
+
+ return true;
+ }
+ bool testForMissingAssertions( Counts& assertions ) {
+ if( assertions.total() != 0 )
+ return false;
+ if( !m_config->warnAboutMissingAssertions() )
+ return false;
+ if( m_trackerContext.currentTracker().hasChildren() )
+ return false;
+ m_totals.assertions.failed++;
+ assertions.failed++;
+ return true;
+ }
+
+ virtual void sectionEnded( SectionEndInfo const& endInfo ) {
+ Counts assertions = m_totals.assertions - endInfo.prevAssertions;
+ bool missingAssertions = testForMissingAssertions( assertions );
+
+ if( !m_activeSections.empty() ) {
+ m_activeSections.back()->close();
+ m_activeSections.pop_back();
+ }
+
+ m_reporter->sectionEnded( SectionStats( endInfo.sectionInfo, assertions, endInfo.durationInSeconds, missingAssertions ) );
+ m_messages.clear();
+ }
+
+ virtual void sectionEndedEarly( SectionEndInfo const& endInfo ) {
+ if( m_unfinishedSections.empty() )
+ m_activeSections.back()->fail();
+ else
+ m_activeSections.back()->close();
+ m_activeSections.pop_back();
+
+ m_unfinishedSections.push_back( endInfo );
+ }
+
+ virtual void pushScopedMessage( MessageInfo const& message ) {
+ m_messages.push_back( message );
+ }
+
+ virtual void popScopedMessage( MessageInfo const& message ) {
+ m_messages.erase( std::remove( m_messages.begin(), m_messages.end(), message ), m_messages.end() );
+ }
+
+ virtual std::string getCurrentTestName() const {
+ return m_activeTestCase
+ ? m_activeTestCase->getTestCaseInfo().name
+ : "";
+ }
+
+ virtual const AssertionResult* getLastResult() const {
+ return &m_lastResult;
+ }
+
+ virtual void handleFatalErrorCondition( std::string const& message ) {
+ ResultBuilder resultBuilder = makeUnexpectedResultBuilder();
+ resultBuilder.setResultType( ResultWas::FatalErrorCondition );
+ resultBuilder << message;
+ resultBuilder.captureExpression();
+
+ handleUnfinishedSections();
+
+ // Recreate section for test case (as we will lose the one that was in scope)
+ TestCaseInfo const& testCaseInfo = m_activeTestCase->getTestCaseInfo();
+ SectionInfo testCaseSection( testCaseInfo.lineInfo, testCaseInfo.name, testCaseInfo.description );
+
+ Counts assertions;
+ assertions.failed = 1;
+ SectionStats testCaseSectionStats( testCaseSection, assertions, 0, false );
+ m_reporter->sectionEnded( testCaseSectionStats );
+
+ TestCaseInfo testInfo = m_activeTestCase->getTestCaseInfo();
+
+ Totals deltaTotals;
+ deltaTotals.testCases.failed = 1;
+ m_reporter->testCaseEnded( TestCaseStats( testInfo,
+ deltaTotals,
+ "",
+ "",
+ false ) );
+ m_totals.testCases.failed++;
+ testGroupEnded( "", m_totals, 1, 1 );
+ m_reporter->testRunEnded( TestRunStats( m_runInfo, m_totals, false ) );
+ }
+
+ public:
+ // !TBD We need to do this another way!
+ bool aborting() const {
+ return m_totals.assertions.failed == static_cast<std::size_t>( m_config->abortAfter() );
+ }
+
+ private:
+
+ void runCurrentTest( std::string& redirectedCout, std::string& redirectedCerr ) {
+ TestCaseInfo const& testCaseInfo = m_activeTestCase->getTestCaseInfo();
+ SectionInfo testCaseSection( testCaseInfo.lineInfo, testCaseInfo.name, testCaseInfo.description );
+ m_reporter->sectionStarting( testCaseSection );
+ Counts prevAssertions = m_totals.assertions;
+ double duration = 0;
+ try {
+ m_lastAssertionInfo = AssertionInfo( "TEST_CASE", testCaseInfo.lineInfo, "", ResultDisposition::Normal );
+
+ seedRng( *m_config );
+
+ Timer timer;
+ timer.start();
+ if( m_reporter->getPreferences().shouldRedirectStdOut ) {
+ StreamRedirect coutRedir( Catch::cout(), redirectedCout );
+ StreamRedirect cerrRedir( Catch::cerr(), redirectedCerr );
+ invokeActiveTestCase();
+ }
+ else {
+ invokeActiveTestCase();
+ }
+ duration = timer.getElapsedSeconds();
+ }
+ catch( TestFailureException& ) {
+ // This just means the test was aborted due to failure
+ }
+ catch(...) {
+ makeUnexpectedResultBuilder().useActiveException();
+ }
+ m_testCaseTracker->close();
+ handleUnfinishedSections();
+ m_messages.clear();
+
+ Counts assertions = m_totals.assertions - prevAssertions;
+ bool missingAssertions = testForMissingAssertions( assertions );
+
+ if( testCaseInfo.okToFail() ) {
+ std::swap( assertions.failedButOk, assertions.failed );
+ m_totals.assertions.failed -= assertions.failedButOk;
+ m_totals.assertions.failedButOk += assertions.failedButOk;
+ }
+
+ SectionStats testCaseSectionStats( testCaseSection, assertions, duration, missingAssertions );
+ m_reporter->sectionEnded( testCaseSectionStats );
+ }
+
+ void invokeActiveTestCase() {
+ FatalConditionHandler fatalConditionHandler; // Handle signals
+ m_activeTestCase->invoke();
+ fatalConditionHandler.reset();
+ }
+
+ private:
+
+ ResultBuilder makeUnexpectedResultBuilder() const {
+ return ResultBuilder( m_lastAssertionInfo.macroName.c_str(),
+ m_lastAssertionInfo.lineInfo,
+ m_lastAssertionInfo.capturedExpression.c_str(),
+ m_lastAssertionInfo.resultDisposition );
+ }
+
+ void handleUnfinishedSections() {
+ // If sections ended prematurely due to an exception we stored their
+ // infos here so we can tear them down outside the unwind process.
+ for( std::vector<SectionEndInfo>::const_reverse_iterator it = m_unfinishedSections.rbegin(),
+ itEnd = m_unfinishedSections.rend();
+ it != itEnd;
+ ++it )
+ sectionEnded( *it );
+ m_unfinishedSections.clear();
+ }
+
+ TestRunInfo m_runInfo;
+ IMutableContext& m_context;
+ TestCase const* m_activeTestCase;
+ ITracker* m_testCaseTracker;
+ ITracker* m_currentSectionTracker;
+ AssertionResult m_lastResult;
+
+ Ptr<IConfig const> m_config;
+ Totals m_totals;
+ Ptr<IStreamingReporter> m_reporter;
+ std::vector<MessageInfo> m_messages;
+ AssertionInfo m_lastAssertionInfo;
+ std::vector<SectionEndInfo> m_unfinishedSections;
+ std::vector<ITracker*> m_activeSections;
+ TrackerContext m_trackerContext;
+ };
+
+ IResultCapture& getResultCapture() {
+ if( IResultCapture* capture = getCurrentContext().getResultCapture() )
+ return *capture;
+ else
+ throw std::logic_error( "No result capture instance" );
+ }
+
+} // end namespace Catch
+
+// #included from: internal/catch_version.h
+#define TWOBLUECUBES_CATCH_VERSION_H_INCLUDED
+
+namespace Catch {
+
+ // Versioning information
+ struct Version {
+ Version( unsigned int _majorVersion,
+ unsigned int _minorVersion,
+ unsigned int _patchNumber,
+ std::string const& _branchName,
+ unsigned int _buildNumber );
+
+ unsigned int const majorVersion;
+ unsigned int const minorVersion;
+ unsigned int const patchNumber;
+
+ // buildNumber is only used if branchName is not null
+ std::string const branchName;
+ unsigned int const buildNumber;
+
+ friend std::ostream& operator << ( std::ostream& os, Version const& version );
+
+ private:
+ void operator=( Version const& );
+ };
+
+ extern Version libraryVersion;
+}
+
+#include <fstream>
+#include <stdlib.h>
+#include <limits>
+
+namespace Catch {
+
+ Ptr<IStreamingReporter> createReporter( std::string const& reporterName, Ptr<Config> const& config ) {
+ Ptr<IStreamingReporter> reporter = getRegistryHub().getReporterRegistry().create( reporterName, config.get() );
+ if( !reporter ) {
+ std::ostringstream oss;
+ oss << "No reporter registered with name: '" << reporterName << "'";
+ throw std::domain_error( oss.str() );
+ }
+ return reporter;
+ }
+
+ Ptr<IStreamingReporter> makeReporter( Ptr<Config> const& config ) {
+ std::vector<std::string> reporters = config->getReporterNames();
+ if( reporters.empty() )
+ reporters.push_back( "console" );
+
+ Ptr<IStreamingReporter> reporter;
+ for( std::vector<std::string>::const_iterator it = reporters.begin(), itEnd = reporters.end();
+ it != itEnd;
+ ++it )
+ reporter = addReporter( reporter, createReporter( *it, config ) );
+ return reporter;
+ }
+ Ptr<IStreamingReporter> addListeners( Ptr<IConfig const> const& config, Ptr<IStreamingReporter> reporters ) {
+ IReporterRegistry::Listeners listeners = getRegistryHub().getReporterRegistry().getListeners();
+ for( IReporterRegistry::Listeners::const_iterator it = listeners.begin(), itEnd = listeners.end();
+ it != itEnd;
+ ++it )
+ reporters = addReporter(reporters, (*it)->create( ReporterConfig( config ) ) );
+ return reporters;
+ }
+
+ Totals runTests( Ptr<Config> const& config ) {
+
+ Ptr<IConfig const> iconfig = config.get();
+
+ Ptr<IStreamingReporter> reporter = makeReporter( config );
+ reporter = addListeners( iconfig, reporter );
+
+ RunContext context( iconfig, reporter );
+
+ Totals totals;
+
+ context.testGroupStarting( config->name(), 1, 1 );
+
+ TestSpec testSpec = config->testSpec();
+ if( !testSpec.hasFilters() )
+ testSpec = TestSpecParser( ITagAliasRegistry::get() ).parse( "~[.]" ).testSpec(); // All not hidden tests
+
+ std::vector<TestCase> const& allTestCases = getAllTestCasesSorted( *iconfig );
+ for( std::vector<TestCase>::const_iterator it = allTestCases.begin(), itEnd = allTestCases.end();
+ it != itEnd;
+ ++it ) {
+ if( !context.aborting() && matchTest( *it, testSpec, *iconfig ) )
+ totals += context.runTest( *it );
+ else
+ reporter->skipTest( *it );
+ }
+
+ context.testGroupEnded( iconfig->name(), totals, 1, 1 );
+ return totals;
+ }
+
+ void applyFilenamesAsTags( IConfig const& config ) {
+ std::vector<TestCase> const& tests = getAllTestCasesSorted( config );
+ for(std::size_t i = 0; i < tests.size(); ++i ) {
+ TestCase& test = const_cast<TestCase&>( tests[i] );
+ std::set<std::string> tags = test.tags;
+
+ std::string filename = test.lineInfo.file;
+ std::string::size_type lastSlash = filename.find_last_of( "\\/" );
+ if( lastSlash != std::string::npos )
+ filename = filename.substr( lastSlash+1 );
+
+ std::string::size_type lastDot = filename.find_last_of( "." );
+ if( lastDot != std::string::npos )
+ filename = filename.substr( 0, lastDot );
+
+ tags.insert( "#" + filename );
+ setTags( test, tags );
+ }
+ }
+
+ class Session : NonCopyable {
+ static bool alreadyInstantiated;
+
+ public:
+
+ struct OnUnusedOptions { enum DoWhat { Ignore, Fail }; };
+
+ Session()
+ : m_cli( makeCommandLineParser() ) {
+ if( alreadyInstantiated ) {
+ std::string msg = "Only one instance of Catch::Session can ever be used";
+ Catch::cerr() << msg << std::endl;
+ throw std::logic_error( msg );
+ }
+ alreadyInstantiated = true;
+ }
+ ~Session() {
+ Catch::cleanUp();
+ }
+
+ void showHelp( std::string const& processName ) {
+ Catch::cout() << "\nCatch v" << libraryVersion << "\n";
+
+ m_cli.usage( Catch::cout(), processName );
+ Catch::cout() << "For more detail usage please see the project docs\n" << std::endl;
+ }
+
+ int applyCommandLine( int argc, char const* const* const argv, OnUnusedOptions::DoWhat unusedOptionBehaviour = OnUnusedOptions::Fail ) {
+ try {
+ m_cli.setThrowOnUnrecognisedTokens( unusedOptionBehaviour == OnUnusedOptions::Fail );
+ m_unusedTokens = m_cli.parseInto( Clara::argsToVector( argc, argv ), m_configData );
+ if( m_configData.showHelp )
+ showHelp( m_configData.processName );
+ m_config.reset();
+ }
+ catch( std::exception& ex ) {
+ {
+ Colour colourGuard( Colour::Red );
+ Catch::cerr()
+ << "\nError(s) in input:\n"
+ << Text( ex.what(), TextAttributes().setIndent(2) )
+ << "\n\n";
+ }
+ m_cli.usage( Catch::cout(), m_configData.processName );
+ return (std::numeric_limits<int>::max)();
+ }
+ return 0;
+ }
+
+ void useConfigData( ConfigData const& _configData ) {
+ m_configData = _configData;
+ m_config.reset();
+ }
+
+ int run( int argc, char const* const* const argv ) {
+
+ int returnCode = applyCommandLine( argc, argv );
+ if( returnCode == 0 )
+ returnCode = run();
+ return returnCode;
+ }
+
+ int run() {
+ if( m_configData.showHelp )
+ return 0;
+
+ try
+ {
+ config(); // Force config to be constructed
+
+ seedRng( *m_config );
+
+ if( m_configData.filenamesAsTags )
+ applyFilenamesAsTags( *m_config );
+
+ // Handle list request
+ if( Option<std::size_t> listed = list( config() ) )
+ return static_cast<int>( *listed );
+
+ return static_cast<int>( runTests( m_config ).assertions.failed );
+ }
+ catch( std::exception& ex ) {
+ Catch::cerr() << ex.what() << std::endl;
+ return (std::numeric_limits<int>::max)();
+ }
+ }
+
+ Clara::CommandLine<ConfigData> const& cli() const {
+ return m_cli;
+ }
+ std::vector<Clara::Parser::Token> const& unusedTokens() const {
+ return m_unusedTokens;
+ }
+ ConfigData& configData() {
+ return m_configData;
+ }
+ Config& config() {
+ if( !m_config )
+ m_config = new Config( m_configData );
+ return *m_config;
+ }
+ private:
+ Clara::CommandLine<ConfigData> m_cli;
+ std::vector<Clara::Parser::Token> m_unusedTokens;
+ ConfigData m_configData;
+ Ptr<Config> m_config;
+ };
+
+ bool Session::alreadyInstantiated = false;
+
+} // end namespace Catch
+
+// #included from: catch_registry_hub.hpp
+#define TWOBLUECUBES_CATCH_REGISTRY_HUB_HPP_INCLUDED
+
+// #included from: catch_test_case_registry_impl.hpp
+#define TWOBLUECUBES_CATCH_TEST_CASE_REGISTRY_IMPL_HPP_INCLUDED
+
+#include <vector>
+#include <set>
+#include <sstream>
+#include <iostream>
+#include <algorithm>
+
+namespace Catch {
+
+ struct LexSort {
+ bool operator() (TestCase i,TestCase j) const { return (i<j);}
+ };
+ struct RandomNumberGenerator {
+ int operator()( int n ) const { return std::rand() % n; }
+ };
+
+ inline std::vector<TestCase> sortTests( IConfig const& config, std::vector<TestCase> const& unsortedTestCases ) {
+
+ std::vector<TestCase> sorted = unsortedTestCases;
+
+ switch( config.runOrder() ) {
+ case RunTests::InLexicographicalOrder:
+ std::sort( sorted.begin(), sorted.end(), LexSort() );
+ break;
+ case RunTests::InRandomOrder:
+ {
+ seedRng( config );
+
+ RandomNumberGenerator rng;
+ std::random_shuffle( sorted.begin(), sorted.end(), rng );
+ }
+ break;
+ case RunTests::InDeclarationOrder:
+ // already in declaration order
+ break;
+ }
+ return sorted;
+ }
+ bool matchTest( TestCase const& testCase, TestSpec const& testSpec, IConfig const& config ) {
+ return testSpec.matches( testCase ) && ( config.allowThrows() || !testCase.throws() );
+ }
+
+ void enforceNoDuplicateTestCases( std::vector<TestCase> const& functions ) {
+ std::set<TestCase> seenFunctions;
+ for( std::vector<TestCase>::const_iterator it = functions.begin(), itEnd = functions.end();
+ it != itEnd;
+ ++it ) {
+ std::pair<std::set<TestCase>::const_iterator, bool> prev = seenFunctions.insert( *it );
+ if( !prev.second ) {
+ std::ostringstream ss;
+
+ ss << Colour( Colour::Red )
+ << "error: TEST_CASE( \"" << it->name << "\" ) already defined.\n"
+ << "\tFirst seen at " << prev.first->getTestCaseInfo().lineInfo << "\n"
+ << "\tRedefined at " << it->getTestCaseInfo().lineInfo << std::endl;
+
+ throw std::runtime_error(ss.str());
+ }
+ }
+ }
+
+ std::vector<TestCase> filterTests( std::vector<TestCase> const& testCases, TestSpec const& testSpec, IConfig const& config ) {
+ std::vector<TestCase> filtered;
+ filtered.reserve( testCases.size() );
+ for( std::vector<TestCase>::const_iterator it = testCases.begin(), itEnd = testCases.end();
+ it != itEnd;
+ ++it )
+ if( matchTest( *it, testSpec, config ) )
+ filtered.push_back( *it );
+ return filtered;
+ }
+ std::vector<TestCase> const& getAllTestCasesSorted( IConfig const& config ) {
+ return getRegistryHub().getTestCaseRegistry().getAllTestsSorted( config );
+ }
+
+ class TestRegistry : public ITestCaseRegistry {
+ public:
+ TestRegistry()
+ : m_currentSortOrder( RunTests::InDeclarationOrder ),
+ m_unnamedCount( 0 )
+ {}
+ virtual ~TestRegistry();
+
+ virtual void registerTest( TestCase const& testCase ) {
+ std::string name = testCase.getTestCaseInfo().name;
+ if( name == "" ) {
+ std::ostringstream oss;
+ oss << "Anonymous test case " << ++m_unnamedCount;
+ return registerTest( testCase.withName( oss.str() ) );
+ }
+ m_functions.push_back( testCase );
+ }
+
+ virtual std::vector<TestCase> const& getAllTests() const {
+ return m_functions;
+ }
+ virtual std::vector<TestCase> const& getAllTestsSorted( IConfig const& config ) const {
+ if( m_sortedFunctions.empty() )
+ enforceNoDuplicateTestCases( m_functions );
+
+ if( m_currentSortOrder != config.runOrder() || m_sortedFunctions.empty() ) {
+ m_sortedFunctions = sortTests( config, m_functions );
+ m_currentSortOrder = config.runOrder();
+ }
+ return m_sortedFunctions;
+ }
+
+ private:
+ std::vector<TestCase> m_functions;
+ mutable RunTests::InWhatOrder m_currentSortOrder;
+ mutable std::vector<TestCase> m_sortedFunctions;
+ size_t m_unnamedCount;
+ std::ios_base::Init m_ostreamInit; // Forces cout/ cerr to be initialised
+ };
+
+ ///////////////////////////////////////////////////////////////////////////
+
+ class FreeFunctionTestCase : public SharedImpl<ITestCase> {
+ public:
+
+ FreeFunctionTestCase( TestFunction fun ) : m_fun( fun ) {}
+
+ virtual void invoke() const {
+ m_fun();
+ }
+
+ private:
+ virtual ~FreeFunctionTestCase();
+
+ TestFunction m_fun;
+ };
+
+ inline std::string extractClassName( std::string const& classOrQualifiedMethodName ) {
+ std::string className = classOrQualifiedMethodName;
+ if( startsWith( className, "&" ) )
+ {
+ std::size_t lastColons = className.rfind( "::" );
+ std::size_t penultimateColons = className.rfind( "::", lastColons-1 );
+ if( penultimateColons == std::string::npos )
+ penultimateColons = 1;
+ className = className.substr( penultimateColons, lastColons-penultimateColons );
+ }
+ return className;
+ }
+
+ void registerTestCase
+ ( ITestCase* testCase,
+ char const* classOrQualifiedMethodName,
+ NameAndDesc const& nameAndDesc,
+ SourceLineInfo const& lineInfo ) {
+
+ getMutableRegistryHub().registerTest
+ ( makeTestCase
+ ( testCase,
+ extractClassName( classOrQualifiedMethodName ),
+ nameAndDesc.name,
+ nameAndDesc.description,
+ lineInfo ) );
+ }
+ void registerTestCaseFunction
+ ( TestFunction function,
+ SourceLineInfo const& lineInfo,
+ NameAndDesc const& nameAndDesc ) {
+ registerTestCase( new FreeFunctionTestCase( function ), "", nameAndDesc, lineInfo );
+ }
+
+ ///////////////////////////////////////////////////////////////////////////
+
+ AutoReg::AutoReg
+ ( TestFunction function,
+ SourceLineInfo const& lineInfo,
+ NameAndDesc const& nameAndDesc ) {
+ registerTestCaseFunction( function, lineInfo, nameAndDesc );
+ }
+
+ AutoReg::~AutoReg() {}
+
+} // end namespace Catch
+
+// #included from: catch_reporter_registry.hpp
+#define TWOBLUECUBES_CATCH_REPORTER_REGISTRY_HPP_INCLUDED
+
+#include <map>
+
+namespace Catch {
+
+ class ReporterRegistry : public IReporterRegistry {
+
+ public:
+
+ virtual ~ReporterRegistry() CATCH_OVERRIDE {}
+
+ virtual IStreamingReporter* create( std::string const& name, Ptr<IConfig const> const& config ) const CATCH_OVERRIDE {
+ FactoryMap::const_iterator it = m_factories.find( name );
+ if( it == m_factories.end() )
+ return CATCH_NULL;
+ return it->second->create( ReporterConfig( config ) );
+ }
+
+ void registerReporter( std::string const& name, Ptr<IReporterFactory> const& factory ) {
+ m_factories.insert( std::make_pair( name, factory ) );
+ }
+ void registerListener( Ptr<IReporterFactory> const& factory ) {
+ m_listeners.push_back( factory );
+ }
+
+ virtual FactoryMap const& getFactories() const CATCH_OVERRIDE {
+ return m_factories;
+ }
+ virtual Listeners const& getListeners() const CATCH_OVERRIDE {
+ return m_listeners;
+ }
+
+ private:
+ FactoryMap m_factories;
+ Listeners m_listeners;
+ };
+}
+
+// #included from: catch_exception_translator_registry.hpp
+#define TWOBLUECUBES_CATCH_EXCEPTION_TRANSLATOR_REGISTRY_HPP_INCLUDED
+
+#ifdef __OBJC__
+#import "Foundation/Foundation.h"
+#endif
+
+namespace Catch {
+
+ class ExceptionTranslatorRegistry : public IExceptionTranslatorRegistry {
+ public:
+ ~ExceptionTranslatorRegistry() {
+ deleteAll( m_translators );
+ }
+
+ virtual void registerTranslator( const IExceptionTranslator* translator ) {
+ m_translators.push_back( translator );
+ }
+
+ virtual std::string translateActiveException() const {
+ try {
+#ifdef __OBJC__
+ // In Objective-C try objective-c exceptions first
+ @try {
+ return tryTranslators();
+ }
+ @catch (NSException *exception) {
+ return Catch::toString( [exception description] );
+ }
+#else
+ return tryTranslators();
+#endif
+ }
+ catch( TestFailureException& ) {
+ throw;
+ }
+ catch( std::exception& ex ) {
+ return ex.what();
+ }
+ catch( std::string& msg ) {
+ return msg;
+ }
+ catch( const char* msg ) {
+ return msg;
+ }
+ catch(...) {
+ return "Unknown exception";
+ }
+ }
+
+ std::string tryTranslators() const {
+ if( m_translators.empty() )
+ throw;
+ else
+ return m_translators[0]->translate( m_translators.begin()+1, m_translators.end() );
+ }
+
+ private:
+ std::vector<const IExceptionTranslator*> m_translators;
+ };
+}
+
+namespace Catch {
+
+ namespace {
+
+ class RegistryHub : public IRegistryHub, public IMutableRegistryHub {
+
+ RegistryHub( RegistryHub const& );
+ void operator=( RegistryHub const& );
+
+ public: // IRegistryHub
+ RegistryHub() {
+ }
+ virtual IReporterRegistry const& getReporterRegistry() const CATCH_OVERRIDE {
+ return m_reporterRegistry;
+ }
+ virtual ITestCaseRegistry const& getTestCaseRegistry() const CATCH_OVERRIDE {
+ return m_testCaseRegistry;
+ }
+ virtual IExceptionTranslatorRegistry& getExceptionTranslatorRegistry() CATCH_OVERRIDE {
+ return m_exceptionTranslatorRegistry;
+ }
+
+ public: // IMutableRegistryHub
+ virtual void registerReporter( std::string const& name, Ptr<IReporterFactory> const& factory ) CATCH_OVERRIDE {
+ m_reporterRegistry.registerReporter( name, factory );
+ }
+ virtual void registerListener( Ptr<IReporterFactory> const& factory ) CATCH_OVERRIDE {
+ m_reporterRegistry.registerListener( factory );
+ }
+ virtual void registerTest( TestCase const& testInfo ) CATCH_OVERRIDE {
+ m_testCaseRegistry.registerTest( testInfo );
+ }
+ virtual void registerTranslator( const IExceptionTranslator* translator ) CATCH_OVERRIDE {
+ m_exceptionTranslatorRegistry.registerTranslator( translator );
+ }
+
+ private:
+ TestRegistry m_testCaseRegistry;
+ ReporterRegistry m_reporterRegistry;
+ ExceptionTranslatorRegistry m_exceptionTranslatorRegistry;
+ };
+
+ // Single, global, instance
+ inline RegistryHub*& getTheRegistryHub() {
+ static RegistryHub* theRegistryHub = CATCH_NULL;
+ if( !theRegistryHub )
+ theRegistryHub = new RegistryHub();
+ return theRegistryHub;
+ }
+ }
+
+ IRegistryHub& getRegistryHub() {
+ return *getTheRegistryHub();
+ }
+ IMutableRegistryHub& getMutableRegistryHub() {
+ return *getTheRegistryHub();
+ }
+ void cleanUp() {
+ delete getTheRegistryHub();
+ getTheRegistryHub() = CATCH_NULL;
+ cleanUpContext();
+ }
+ std::string translateActiveException() {
+ return getRegistryHub().getExceptionTranslatorRegistry().translateActiveException();
+ }
+
+} // end namespace Catch
+
+// #included from: catch_notimplemented_exception.hpp
+#define TWOBLUECUBES_CATCH_NOTIMPLEMENTED_EXCEPTION_HPP_INCLUDED
+
+#include <ostream>
+
+namespace Catch {
+
+ NotImplementedException::NotImplementedException( SourceLineInfo const& lineInfo )
+ : m_lineInfo( lineInfo ) {
+ std::ostringstream oss;
+ oss << lineInfo << ": function ";
+ oss << "not implemented";
+ m_what = oss.str();
+ }
+
+ const char* NotImplementedException::what() const CATCH_NOEXCEPT {
+ return m_what.c_str();
+ }
+
+} // end namespace Catch
+
+// #included from: catch_context_impl.hpp
+#define TWOBLUECUBES_CATCH_CONTEXT_IMPL_HPP_INCLUDED
+
+// #included from: catch_stream.hpp
+#define TWOBLUECUBES_CATCH_STREAM_HPP_INCLUDED
+
+#include <stdexcept>
+#include <cstdio>
+#include <iostream>
+
+namespace Catch {
+
+ template<typename WriterF, size_t bufferSize=256>
+ class StreamBufImpl : public StreamBufBase {
+ char data[bufferSize];
+ WriterF m_writer;
+
+ public:
+ StreamBufImpl() {
+ setp( data, data + sizeof(data) );
+ }
+
+ ~StreamBufImpl() CATCH_NOEXCEPT {
+ sync();
+ }
+
+ private:
+ int overflow( int c ) {
+ sync();
+
+ if( c != EOF ) {
+ if( pbase() == epptr() )
+ m_writer( std::string( 1, static_cast<char>( c ) ) );
+ else
+ sputc( static_cast<char>( c ) );
+ }
+ return 0;
+ }
+
+ int sync() {
+ if( pbase() != pptr() ) {
+ m_writer( std::string( pbase(), static_cast<std::string::size_type>( pptr() - pbase() ) ) );
+ setp( pbase(), epptr() );
+ }
+ return 0;
+ }
+ };
+
+ ///////////////////////////////////////////////////////////////////////////
+
+ FileStream::FileStream( std::string const& filename ) {
+ m_ofs.open( filename.c_str() );
+ if( m_ofs.fail() ) {
+ std::ostringstream oss;
+ oss << "Unable to open file: '" << filename << "'";
+ throw std::domain_error( oss.str() );
+ }
+ }
+
+ std::ostream& FileStream::stream() const {
+ return m_ofs;
+ }
+
+ struct OutputDebugWriter {
+
+ void operator()( std::string const&str ) {
+ writeToDebugConsole( str );
+ }
+ };
+
+ DebugOutStream::DebugOutStream()
+ : m_streamBuf( new StreamBufImpl<OutputDebugWriter>() ),
+ m_os( m_streamBuf.get() )
+ {}
+
+ std::ostream& DebugOutStream::stream() const {
+ return m_os;
+ }
+
+ // Store the streambuf from cout up-front because
+ // cout may get redirected when running tests
+ CoutStream::CoutStream()
+ : m_os( Catch::cout().rdbuf() )
+ {}
+
+ std::ostream& CoutStream::stream() const {
+ return m_os;
+ }
+
+#ifndef CATCH_CONFIG_NOSTDOUT // If you #define this you must implement these functions
+ std::ostream& cout() {
+ return std::cout;
+ }
+ std::ostream& cerr() {
+ return std::cerr;
+ }
+#endif
+}
+
+namespace Catch {
+
+ class Context : public IMutableContext {
+
+ Context() : m_config( CATCH_NULL ), m_runner( CATCH_NULL ), m_resultCapture( CATCH_NULL ) {}
+ Context( Context const& );
+ void operator=( Context const& );
+
+ public: // IContext
+ virtual IResultCapture* getResultCapture() {
+ return m_resultCapture;
+ }
+ virtual IRunner* getRunner() {
+ return m_runner;
+ }
+ virtual size_t getGeneratorIndex( std::string const& fileInfo, size_t totalSize ) {
+ return getGeneratorsForCurrentTest()
+ .getGeneratorInfo( fileInfo, totalSize )
+ .getCurrentIndex();
+ }
+ virtual bool advanceGeneratorsForCurrentTest() {
+ IGeneratorsForTest* generators = findGeneratorsForCurrentTest();
+ return generators && generators->moveNext();
+ }
+
+ virtual Ptr<IConfig const> getConfig() const {
+ return m_config;
+ }
+
+ public: // IMutableContext
+ virtual void setResultCapture( IResultCapture* resultCapture ) {
+ m_resultCapture = resultCapture;
+ }
+ virtual void setRunner( IRunner* runner ) {
+ m_runner = runner;
+ }
+ virtual void setConfig( Ptr<IConfig const> const& config ) {
+ m_config = config;
+ }
+
+ friend IMutableContext& getCurrentMutableContext();
+
+ private:
+ IGeneratorsForTest* findGeneratorsForCurrentTest() {
+ std::string testName = getResultCapture()->getCurrentTestName();
+
+ std::map<std::string, IGeneratorsForTest*>::const_iterator it =
+ m_generatorsByTestName.find( testName );
+ return it != m_generatorsByTestName.end()
+ ? it->second
+ : CATCH_NULL;
+ }
+
+ IGeneratorsForTest& getGeneratorsForCurrentTest() {
+ IGeneratorsForTest* generators = findGeneratorsForCurrentTest();
+ if( !generators ) {
+ std::string testName = getResultCapture()->getCurrentTestName();
+ generators = createGeneratorsForTest();
+ m_generatorsByTestName.insert( std::make_pair( testName, generators ) );
+ }
+ return *generators;
+ }
+
+ private:
+ Ptr<IConfig const> m_config;
+ IRunner* m_runner;
+ IResultCapture* m_resultCapture;
+ std::map<std::string, IGeneratorsForTest*> m_generatorsByTestName;
+ };
+
+ namespace {
+ Context* currentContext = CATCH_NULL;
+ }
+ IMutableContext& getCurrentMutableContext() {
+ if( !currentContext )
+ currentContext = new Context();
+ return *currentContext;
+ }
+ IContext& getCurrentContext() {
+ return getCurrentMutableContext();
+ }
+
+ void cleanUpContext() {
+ delete currentContext;
+ currentContext = CATCH_NULL;
+ }
+}
+
+// #included from: catch_console_colour_impl.hpp
+#define TWOBLUECUBES_CATCH_CONSOLE_COLOUR_IMPL_HPP_INCLUDED
+
+namespace Catch {
+ namespace {
+
+ struct IColourImpl {
+ virtual ~IColourImpl() {}
+ virtual void use( Colour::Code _colourCode ) = 0;
+ };
+
+ struct NoColourImpl : IColourImpl {
+ void use( Colour::Code ) {}
+
+ static IColourImpl* instance() {
+ static NoColourImpl s_instance;
+ return &s_instance;
+ }
+ };
+
+ } // anon namespace
+} // namespace Catch
+
+#if !defined( CATCH_CONFIG_COLOUR_NONE ) && !defined( CATCH_CONFIG_COLOUR_WINDOWS ) && !defined( CATCH_CONFIG_COLOUR_ANSI )
+# ifdef CATCH_PLATFORM_WINDOWS
+# define CATCH_CONFIG_COLOUR_WINDOWS
+# else
+# define CATCH_CONFIG_COLOUR_ANSI
+# endif
+#endif
+
+#if defined ( CATCH_CONFIG_COLOUR_WINDOWS ) /////////////////////////////////////////
+
+#ifndef NOMINMAX
+#define NOMINMAX
+#endif
+
+#ifdef __AFXDLL
+#include <AfxWin.h>
+#else
+#include <windows.h>
+#endif
+
+namespace Catch {
+namespace {
+
+ class Win32ColourImpl : public IColourImpl {
+ public:
+ Win32ColourImpl() : stdoutHandle( GetStdHandle(STD_OUTPUT_HANDLE) )
+ {
+ CONSOLE_SCREEN_BUFFER_INFO csbiInfo;
+ GetConsoleScreenBufferInfo( stdoutHandle, &csbiInfo );
+ originalForegroundAttributes = csbiInfo.wAttributes & ~( BACKGROUND_GREEN | BACKGROUND_RED | BACKGROUND_BLUE | BACKGROUND_INTENSITY );
+ originalBackgroundAttributes = csbiInfo.wAttributes & ~( FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_BLUE | FOREGROUND_INTENSITY );
+ }
+
+ virtual void use( Colour::Code _colourCode ) {
+ switch( _colourCode ) {
+ case Colour::None: return setTextAttribute( originalForegroundAttributes );
+ case Colour::White: return setTextAttribute( FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_BLUE );
+ case Colour::Red: return setTextAttribute( FOREGROUND_RED );
+ case Colour::Green: return setTextAttribute( FOREGROUND_GREEN );
+ case Colour::Blue: return setTextAttribute( FOREGROUND_BLUE );
+ case Colour::Cyan: return setTextAttribute( FOREGROUND_BLUE | FOREGROUND_GREEN );
+ case Colour::Yellow: return setTextAttribute( FOREGROUND_RED | FOREGROUND_GREEN );
+ case Colour::Grey: return setTextAttribute( 0 );
+
+ case Colour::LightGrey: return setTextAttribute( FOREGROUND_INTENSITY );
+ case Colour::BrightRed: return setTextAttribute( FOREGROUND_INTENSITY | FOREGROUND_RED );
+ case Colour::BrightGreen: return setTextAttribute( FOREGROUND_INTENSITY | FOREGROUND_GREEN );
+ case Colour::BrightWhite: return setTextAttribute( FOREGROUND_INTENSITY | FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_BLUE );
+
+ case Colour::Bright: throw std::logic_error( "not a colour" );
+ }
+ }
+
+ private:
+ void setTextAttribute( WORD _textAttribute ) {
+ SetConsoleTextAttribute( stdoutHandle, _textAttribute | originalBackgroundAttributes );
+ }
+ HANDLE stdoutHandle;
+ WORD originalForegroundAttributes;
+ WORD originalBackgroundAttributes;
+ };
+
+ IColourImpl* platformColourInstance() {
+ static Win32ColourImpl s_instance;
+
+ Ptr<IConfig const> config = getCurrentContext().getConfig();
+ UseColour::YesOrNo colourMode = config
+ ? config->useColour()
+ : UseColour::Auto;
+ if( colourMode == UseColour::Auto )
+ colourMode = !isDebuggerActive()
+ ? UseColour::Yes
+ : UseColour::No;
+ return colourMode == UseColour::Yes
+ ? &s_instance
+ : NoColourImpl::instance();
+ }
+
+} // end anon namespace
+} // end namespace Catch
+
+#elif defined( CATCH_CONFIG_COLOUR_ANSI ) //////////////////////////////////////
+
+#include <unistd.h>
+
+namespace Catch {
+namespace {
+
+ // use POSIX/ ANSI console terminal codes
+ // Thanks to Adam Strzelecki for original contribution
+ // (http://github.com/nanoant)
+ // https://github.com/philsquared/Catch/pull/131
+ class PosixColourImpl : public IColourImpl {
+ public:
+ virtual void use( Colour::Code _colourCode ) {
+ switch( _colourCode ) {
+ case Colour::None:
+ case Colour::White: return setColour( "[0m" );
+ case Colour::Red: return setColour( "[0;31m" );
+ case Colour::Green: return setColour( "[0;32m" );
+ case Colour::Blue: return setColour( "[0:34m" );
+ case Colour::Cyan: return setColour( "[0;36m" );
+ case Colour::Yellow: return setColour( "[0;33m" );
+ case Colour::Grey: return setColour( "[1;30m" );
+
+ case Colour::LightGrey: return setColour( "[0;37m" );
+ case Colour::BrightRed: return setColour( "[1;31m" );
+ case Colour::BrightGreen: return setColour( "[1;32m" );
+ case Colour::BrightWhite: return setColour( "[1;37m" );
+
+ case Colour::Bright: throw std::logic_error( "not a colour" );
+ }
+ }
+ static IColourImpl* instance() {
+ static PosixColourImpl s_instance;
+ return &s_instance;
+ }
+
+ private:
+ void setColour( const char* _escapeCode ) {
+ Catch::cout() << '\033' << _escapeCode;
+ }
+ };
+
+ IColourImpl* platformColourInstance() {
+ Ptr<IConfig const> config = getCurrentContext().getConfig();
+ UseColour::YesOrNo colourMode = config
+ ? config->useColour()
+ : UseColour::Auto;
+ if( colourMode == UseColour::Auto )
+ colourMode = (!isDebuggerActive() && isatty(STDOUT_FILENO) )
+ ? UseColour::Yes
+ : UseColour::No;
+ return colourMode == UseColour::Yes
+ ? PosixColourImpl::instance()
+ : NoColourImpl::instance();
+ }
+
+} // end anon namespace
+} // end namespace Catch
+
+#else // not Windows or ANSI ///////////////////////////////////////////////
+
+namespace Catch {
+
+ static IColourImpl* platformColourInstance() { return NoColourImpl::instance(); }
+
+} // end namespace Catch
+
+#endif // Windows/ ANSI/ None
+
+namespace Catch {
+
+ Colour::Colour( Code _colourCode ) : m_moved( false ) { use( _colourCode ); }
+ Colour::Colour( Colour const& _other ) : m_moved( false ) { const_cast<Colour&>( _other ).m_moved = true; }
+ Colour::~Colour(){ if( !m_moved ) use( None ); }
+
+ void Colour::use( Code _colourCode ) {
+ static IColourImpl* impl = platformColourInstance();
+ impl->use( _colourCode );
+ }
+
+} // end namespace Catch
+
+// #included from: catch_generators_impl.hpp
+#define TWOBLUECUBES_CATCH_GENERATORS_IMPL_HPP_INCLUDED
+
+#include <vector>
+#include <string>
+#include <map>
+
+namespace Catch {
+
+ struct GeneratorInfo : IGeneratorInfo {
+
+ GeneratorInfo( std::size_t size )
+ : m_size( size ),
+ m_currentIndex( 0 )
+ {}
+
+ bool moveNext() {
+ if( ++m_currentIndex == m_size ) {
+ m_currentIndex = 0;
+ return false;
+ }
+ return true;
+ }
+
+ std::size_t getCurrentIndex() const {
+ return m_currentIndex;
+ }
+
+ std::size_t m_size;
+ std::size_t m_currentIndex;
+ };
+
+ ///////////////////////////////////////////////////////////////////////////
+
+ class GeneratorsForTest : public IGeneratorsForTest {
+
+ public:
+ ~GeneratorsForTest() {
+ deleteAll( m_generatorsInOrder );
+ }
+
+ IGeneratorInfo& getGeneratorInfo( std::string const& fileInfo, std::size_t size ) {
+ std::map<std::string, IGeneratorInfo*>::const_iterator it = m_generatorsByName.find( fileInfo );
+ if( it == m_generatorsByName.end() ) {
+ IGeneratorInfo* info = new GeneratorInfo( size );
+ m_generatorsByName.insert( std::make_pair( fileInfo, info ) );
+ m_generatorsInOrder.push_back( info );
+ return *info;
+ }
+ return *it->second;
+ }
+
+ bool moveNext() {
+ std::vector<IGeneratorInfo*>::const_iterator it = m_generatorsInOrder.begin();
+ std::vector<IGeneratorInfo*>::const_iterator itEnd = m_generatorsInOrder.end();
+ for(; it != itEnd; ++it ) {
+ if( (*it)->moveNext() )
+ return true;
+ }
+ return false;
+ }
+
+ private:
+ std::map<std::string, IGeneratorInfo*> m_generatorsByName;
+ std::vector<IGeneratorInfo*> m_generatorsInOrder;
+ };
+
+ IGeneratorsForTest* createGeneratorsForTest()
+ {
+ return new GeneratorsForTest();
+ }
+
+} // end namespace Catch
+
+// #included from: catch_assertionresult.hpp
+#define TWOBLUECUBES_CATCH_ASSERTIONRESULT_HPP_INCLUDED
+
+namespace Catch {
+
+ AssertionInfo::AssertionInfo( std::string const& _macroName,
+ SourceLineInfo const& _lineInfo,
+ std::string const& _capturedExpression,
+ ResultDisposition::Flags _resultDisposition )
+ : macroName( _macroName ),
+ lineInfo( _lineInfo ),
+ capturedExpression( _capturedExpression ),
+ resultDisposition( _resultDisposition )
+ {}
+
+ AssertionResult::AssertionResult() {}
+
+ AssertionResult::AssertionResult( AssertionInfo const& info, AssertionResultData const& data )
+ : m_info( info ),
+ m_resultData( data )
+ {}
+
+ AssertionResult::~AssertionResult() {}
+
+ // Result was a success
+ bool AssertionResult::succeeded() const {
+ return Catch::isOk( m_resultData.resultType );
+ }
+
+ // Result was a success, or failure is suppressed
+ bool AssertionResult::isOk() const {
+ return Catch::isOk( m_resultData.resultType ) || shouldSuppressFailure( m_info.resultDisposition );
+ }
+
+ ResultWas::OfType AssertionResult::getResultType() const {
+ return m_resultData.resultType;
+ }
+
+ bool AssertionResult::hasExpression() const {
+ return !m_info.capturedExpression.empty();
+ }
+
+ bool AssertionResult::hasMessage() const {
+ return !m_resultData.message.empty();
+ }
+
+ std::string AssertionResult::getExpression() const {
+ if( isFalseTest( m_info.resultDisposition ) )
+ return "!" + m_info.capturedExpression;
+ else
+ return m_info.capturedExpression;
+ }
+ std::string AssertionResult::getExpressionInMacro() const {
+ if( m_info.macroName.empty() )
+ return m_info.capturedExpression;
+ else
+ return m_info.macroName + "( " + m_info.capturedExpression + " )";
+ }
+
+ bool AssertionResult::hasExpandedExpression() const {
+ return hasExpression() && getExpandedExpression() != getExpression();
+ }
+
+ std::string AssertionResult::getExpandedExpression() const {
+ return m_resultData.reconstructedExpression;
+ }
+
+ std::string AssertionResult::getMessage() const {
+ return m_resultData.message;
+ }
+ SourceLineInfo AssertionResult::getSourceInfo() const {
+ return m_info.lineInfo;
+ }
+
+ std::string AssertionResult::getTestMacroName() const {
+ return m_info.macroName;
+ }
+
+} // end namespace Catch
+
+// #included from: catch_test_case_info.hpp
+#define TWOBLUECUBES_CATCH_TEST_CASE_INFO_HPP_INCLUDED
+
+namespace Catch {
+
+ inline TestCaseInfo::SpecialProperties parseSpecialTag( std::string const& tag ) {
+ if( startsWith( tag, "." ) ||
+ tag == "hide" ||
+ tag == "!hide" )
+ return TestCaseInfo::IsHidden;
+ else if( tag == "!throws" )
+ return TestCaseInfo::Throws;
+ else if( tag == "!shouldfail" )
+ return TestCaseInfo::ShouldFail;
+ else if( tag == "!mayfail" )
+ return TestCaseInfo::MayFail;
+ else
+ return TestCaseInfo::None;
+ }
+ inline bool isReservedTag( std::string const& tag ) {
+ return parseSpecialTag( tag ) == TestCaseInfo::None && tag.size() > 0 && !isalnum( tag[0] );
+ }
+ inline void enforceNotReservedTag( std::string const& tag, SourceLineInfo const& _lineInfo ) {
+ if( isReservedTag( tag ) ) {
+ {
+ Colour colourGuard( Colour::Red );
+ Catch::cerr()
+ << "Tag name [" << tag << "] not allowed.\n"
+ << "Tag names starting with non alpha-numeric characters are reserved\n";
+ }
+ {
+ Colour colourGuard( Colour::FileName );
+ Catch::cerr() << _lineInfo << std::endl;
+ }
+ exit(1);
+ }
+ }
+
+ TestCase makeTestCase( ITestCase* _testCase,
+ std::string const& _className,
+ std::string const& _name,
+ std::string const& _descOrTags,
+ SourceLineInfo const& _lineInfo )
+ {
+ bool isHidden( startsWith( _name, "./" ) ); // Legacy support
+
+ // Parse out tags
+ std::set<std::string> tags;
+ std::string desc, tag;
+ bool inTag = false;
+ for( std::size_t i = 0; i < _descOrTags.size(); ++i ) {
+ char c = _descOrTags[i];
+ if( !inTag ) {
+ if( c == '[' )
+ inTag = true;
+ else
+ desc += c;
+ }
+ else {
+ if( c == ']' ) {
+ TestCaseInfo::SpecialProperties prop = parseSpecialTag( tag );
+ if( prop == TestCaseInfo::IsHidden )
+ isHidden = true;
+ else if( prop == TestCaseInfo::None )
+ enforceNotReservedTag( tag, _lineInfo );
+
+ tags.insert( tag );
+ tag.clear();
+ inTag = false;
+ }
+ else
+ tag += c;
+ }
+ }
+ if( isHidden ) {
+ tags.insert( "hide" );
+ tags.insert( "." );
+ }
+
+ TestCaseInfo info( _name, _className, desc, tags, _lineInfo );
+ return TestCase( _testCase, info );
+ }
+
+ void setTags( TestCaseInfo& testCaseInfo, std::set<std::string> const& tags )
+ {
+ testCaseInfo.tags = tags;
+ testCaseInfo.lcaseTags.clear();
+
+ std::ostringstream oss;
+ for( std::set<std::string>::const_iterator it = tags.begin(), itEnd = tags.end(); it != itEnd; ++it ) {
+ oss << "[" << *it << "]";
+ std::string lcaseTag = toLower( *it );
+ testCaseInfo.properties = static_cast<TestCaseInfo::SpecialProperties>( testCaseInfo.properties | parseSpecialTag( lcaseTag ) );
+ testCaseInfo.lcaseTags.insert( lcaseTag );
+ }
+ testCaseInfo.tagsAsString = oss.str();
+ }
+
+ TestCaseInfo::TestCaseInfo( std::string const& _name,
+ std::string const& _className,
+ std::string const& _description,
+ std::set<std::string> const& _tags,
+ SourceLineInfo const& _lineInfo )
+ : name( _name ),
+ className( _className ),
+ description( _description ),
+ lineInfo( _lineInfo ),
+ properties( None )
+ {
+ setTags( *this, _tags );
+ }
+
+ TestCaseInfo::TestCaseInfo( TestCaseInfo const& other )
+ : name( other.name ),
+ className( other.className ),
+ description( other.description ),
+ tags( other.tags ),
+ lcaseTags( other.lcaseTags ),
+ tagsAsString( other.tagsAsString ),
+ lineInfo( other.lineInfo ),
+ properties( other.properties )
+ {}
+
+ bool TestCaseInfo::isHidden() const {
+ return ( properties & IsHidden ) != 0;
+ }
+ bool TestCaseInfo::throws() const {
+ return ( properties & Throws ) != 0;
+ }
+ bool TestCaseInfo::okToFail() const {
+ return ( properties & (ShouldFail | MayFail ) ) != 0;
+ }
+ bool TestCaseInfo::expectedToFail() const {
+ return ( properties & (ShouldFail ) ) != 0;
+ }
+
+ TestCase::TestCase( ITestCase* testCase, TestCaseInfo const& info ) : TestCaseInfo( info ), test( testCase ) {}
+
+ TestCase::TestCase( TestCase const& other )
+ : TestCaseInfo( other ),
+ test( other.test )
+ {}
+
+ TestCase TestCase::withName( std::string const& _newName ) const {
+ TestCase other( *this );
+ other.name = _newName;
+ return other;
+ }
+
+ void TestCase::swap( TestCase& other ) {
+ test.swap( other.test );
+ name.swap( other.name );
+ className.swap( other.className );
+ description.swap( other.description );
+ tags.swap( other.tags );
+ lcaseTags.swap( other.lcaseTags );
+ tagsAsString.swap( other.tagsAsString );
+ std::swap( TestCaseInfo::properties, static_cast<TestCaseInfo&>( other ).properties );
+ std::swap( lineInfo, other.lineInfo );
+ }
+
+ void TestCase::invoke() const {
+ test->invoke();
+ }
+
+ bool TestCase::operator == ( TestCase const& other ) const {
+ return test.get() == other.test.get() &&
+ name == other.name &&
+ className == other.className;
+ }
+
+ bool TestCase::operator < ( TestCase const& other ) const {
+ return name < other.name;
+ }
+ TestCase& TestCase::operator = ( TestCase const& other ) {
+ TestCase temp( other );
+ swap( temp );
+ return *this;
+ }
+
+ TestCaseInfo const& TestCase::getTestCaseInfo() const
+ {
+ return *this;
+ }
+
+} // end namespace Catch
+
+// #included from: catch_version.hpp
+#define TWOBLUECUBES_CATCH_VERSION_HPP_INCLUDED
+
+namespace Catch {
+
+ Version::Version
+ ( unsigned int _majorVersion,
+ unsigned int _minorVersion,
+ unsigned int _patchNumber,
+ std::string const& _branchName,
+ unsigned int _buildNumber )
+ : majorVersion( _majorVersion ),
+ minorVersion( _minorVersion ),
+ patchNumber( _patchNumber ),
+ branchName( _branchName ),
+ buildNumber( _buildNumber )
+ {}
+
+ std::ostream& operator << ( std::ostream& os, Version const& version ) {
+ os << version.majorVersion << "."
+ << version.minorVersion << "."
+ << version.patchNumber;
+
+ if( !version.branchName.empty() ) {
+ os << "-" << version.branchName
+ << "." << version.buildNumber;
+ }
+ return os;
+ }
+
+ Version libraryVersion( 1, 5, 4, "", 0 );
+
+}
+
+// #included from: catch_message.hpp
+#define TWOBLUECUBES_CATCH_MESSAGE_HPP_INCLUDED
+
+namespace Catch {
+
+ MessageInfo::MessageInfo( std::string const& _macroName,
+ SourceLineInfo const& _lineInfo,
+ ResultWas::OfType _type )
+ : macroName( _macroName ),
+ lineInfo( _lineInfo ),
+ type( _type ),
+ sequence( ++globalCount )
+ {}
+
+ // This may need protecting if threading support is added
+ unsigned int MessageInfo::globalCount = 0;
+
+ ////////////////////////////////////////////////////////////////////////////
+
+ ScopedMessage::ScopedMessage( MessageBuilder const& builder )
+ : m_info( builder.m_info )
+ {
+ m_info.message = builder.m_stream.str();
+ getResultCapture().pushScopedMessage( m_info );
+ }
+ ScopedMessage::ScopedMessage( ScopedMessage const& other )
+ : m_info( other.m_info )
+ {}
+
+ ScopedMessage::~ScopedMessage() {
+ getResultCapture().popScopedMessage( m_info );
+ }
+
+} // end namespace Catch
+
+// #included from: catch_legacy_reporter_adapter.hpp
+#define TWOBLUECUBES_CATCH_LEGACY_REPORTER_ADAPTER_HPP_INCLUDED
+
+// #included from: catch_legacy_reporter_adapter.h
+#define TWOBLUECUBES_CATCH_LEGACY_REPORTER_ADAPTER_H_INCLUDED
+
+namespace Catch
+{
+ // Deprecated
+ struct IReporter : IShared {
+ virtual ~IReporter();
+
+ virtual bool shouldRedirectStdout() const = 0;
+
+ virtual void StartTesting() = 0;
+ virtual void EndTesting( Totals const& totals ) = 0;
+ virtual void StartGroup( std::string const& groupName ) = 0;
+ virtual void EndGroup( std::string const& groupName, Totals const& totals ) = 0;
+ virtual void StartTestCase( TestCaseInfo const& testInfo ) = 0;
+ virtual void EndTestCase( TestCaseInfo const& testInfo, Totals const& totals, std::string const& stdOut, std::string const& stdErr ) = 0;
+ virtual void StartSection( std::string const& sectionName, std::string const& description ) = 0;
+ virtual void EndSection( std::string const& sectionName, Counts const& assertions ) = 0;
+ virtual void NoAssertionsInSection( std::string const& sectionName ) = 0;
+ virtual void NoAssertionsInTestCase( std::string const& testName ) = 0;
+ virtual void Aborted() = 0;
+ virtual void Result( AssertionResult const& result ) = 0;
+ };
+
+ class LegacyReporterAdapter : public SharedImpl<IStreamingReporter>
+ {
+ public:
+ LegacyReporterAdapter( Ptr<IReporter> const& legacyReporter );
+ virtual ~LegacyReporterAdapter();
+
+ virtual ReporterPreferences getPreferences() const;
+ virtual void noMatchingTestCases( std::string const& );
+ virtual void testRunStarting( TestRunInfo const& );
+ virtual void testGroupStarting( GroupInfo const& groupInfo );
+ virtual void testCaseStarting( TestCaseInfo const& testInfo );
+ virtual void sectionStarting( SectionInfo const& sectionInfo );
+ virtual void assertionStarting( AssertionInfo const& );
+ virtual bool assertionEnded( AssertionStats const& assertionStats );
+ virtual void sectionEnded( SectionStats const& sectionStats );
+ virtual void testCaseEnded( TestCaseStats const& testCaseStats );
+ virtual void testGroupEnded( TestGroupStats const& testGroupStats );
+ virtual void testRunEnded( TestRunStats const& testRunStats );
+ virtual void skipTest( TestCaseInfo const& );
+
+ private:
+ Ptr<IReporter> m_legacyReporter;
+ };
+}
+
+namespace Catch
+{
+ LegacyReporterAdapter::LegacyReporterAdapter( Ptr<IReporter> const& legacyReporter )
+ : m_legacyReporter( legacyReporter )
+ {}
+ LegacyReporterAdapter::~LegacyReporterAdapter() {}
+
+ ReporterPreferences LegacyReporterAdapter::getPreferences() const {
+ ReporterPreferences prefs;
+ prefs.shouldRedirectStdOut = m_legacyReporter->shouldRedirectStdout();
+ return prefs;
+ }
+
+ void LegacyReporterAdapter::noMatchingTestCases( std::string const& ) {}
+ void LegacyReporterAdapter::testRunStarting( TestRunInfo const& ) {
+ m_legacyReporter->StartTesting();
+ }
+ void LegacyReporterAdapter::testGroupStarting( GroupInfo const& groupInfo ) {
+ m_legacyReporter->StartGroup( groupInfo.name );
+ }
+ void LegacyReporterAdapter::testCaseStarting( TestCaseInfo const& testInfo ) {
+ m_legacyReporter->StartTestCase( testInfo );
+ }
+ void LegacyReporterAdapter::sectionStarting( SectionInfo const& sectionInfo ) {
+ m_legacyReporter->StartSection( sectionInfo.name, sectionInfo.description );
+ }
+ void LegacyReporterAdapter::assertionStarting( AssertionInfo const& ) {
+ // Not on legacy interface
+ }
+
+ bool LegacyReporterAdapter::assertionEnded( AssertionStats const& assertionStats ) {
+ if( assertionStats.assertionResult.getResultType() != ResultWas::Ok ) {
+ for( std::vector<MessageInfo>::const_iterator it = assertionStats.infoMessages.begin(), itEnd = assertionStats.infoMessages.end();
+ it != itEnd;
+ ++it ) {
+ if( it->type == ResultWas::Info ) {
+ ResultBuilder rb( it->macroName.c_str(), it->lineInfo, "", ResultDisposition::Normal );
+ rb << it->message;
+ rb.setResultType( ResultWas::Info );
+ AssertionResult result = rb.build();
+ m_legacyReporter->Result( result );
+ }
+ }
+ }
+ m_legacyReporter->Result( assertionStats.assertionResult );
+ return true;
+ }
+ void LegacyReporterAdapter::sectionEnded( SectionStats const& sectionStats ) {
+ if( sectionStats.missingAssertions )
+ m_legacyReporter->NoAssertionsInSection( sectionStats.sectionInfo.name );
+ m_legacyReporter->EndSection( sectionStats.sectionInfo.name, sectionStats.assertions );
+ }
+ void LegacyReporterAdapter::testCaseEnded( TestCaseStats const& testCaseStats ) {
+ m_legacyReporter->EndTestCase
+ ( testCaseStats.testInfo,
+ testCaseStats.totals,
+ testCaseStats.stdOut,
+ testCaseStats.stdErr );
+ }
+ void LegacyReporterAdapter::testGroupEnded( TestGroupStats const& testGroupStats ) {
+ if( testGroupStats.aborting )
+ m_legacyReporter->Aborted();
+ m_legacyReporter->EndGroup( testGroupStats.groupInfo.name, testGroupStats.totals );
+ }
+ void LegacyReporterAdapter::testRunEnded( TestRunStats const& testRunStats ) {
+ m_legacyReporter->EndTesting( testRunStats.totals );
+ }
+ void LegacyReporterAdapter::skipTest( TestCaseInfo const& ) {
+ }
+}
+
+// #included from: catch_timer.hpp
+
+#ifdef __clang__
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wc++11-long-long"
+#endif
+
+#ifdef CATCH_PLATFORM_WINDOWS
+#include <windows.h>
+#else
+#include <sys/time.h>
+#endif
+
+namespace Catch {
+
+ namespace {
+#ifdef CATCH_PLATFORM_WINDOWS
+ uint64_t getCurrentTicks() {
+ static uint64_t hz=0, hzo=0;
+ if (!hz) {
+ QueryPerformanceFrequency( reinterpret_cast<LARGE_INTEGER*>( &hz ) );
+ QueryPerformanceCounter( reinterpret_cast<LARGE_INTEGER*>( &hzo ) );
+ }
+ uint64_t t;
+ QueryPerformanceCounter( reinterpret_cast<LARGE_INTEGER*>( &t ) );
+ return ((t-hzo)*1000000)/hz;
+ }
+#else
+ uint64_t getCurrentTicks() {
+ timeval t;
+ gettimeofday(&t,CATCH_NULL);
+ return static_cast<uint64_t>( t.tv_sec ) * 1000000ull + static_cast<uint64_t>( t.tv_usec );
+ }
+#endif
+ }
+
+ void Timer::start() {
+ m_ticks = getCurrentTicks();
+ }
+ unsigned int Timer::getElapsedMicroseconds() const {
+ return static_cast<unsigned int>(getCurrentTicks() - m_ticks);
+ }
+ unsigned int Timer::getElapsedMilliseconds() const {
+ return static_cast<unsigned int>(getElapsedMicroseconds()/1000);
+ }
+ double Timer::getElapsedSeconds() const {
+ return getElapsedMicroseconds()/1000000.0;
+ }
+
+} // namespace Catch
+
+#ifdef __clang__
+#pragma clang diagnostic pop
+#endif
+// #included from: catch_common.hpp
+#define TWOBLUECUBES_CATCH_COMMON_HPP_INCLUDED
+
+namespace Catch {
+
+ bool startsWith( std::string const& s, std::string const& prefix ) {
+ return s.size() >= prefix.size() && s.substr( 0, prefix.size() ) == prefix;
+ }
+ bool endsWith( std::string const& s, std::string const& suffix ) {
+ return s.size() >= suffix.size() && s.substr( s.size()-suffix.size(), suffix.size() ) == suffix;
+ }
+ bool contains( std::string const& s, std::string const& infix ) {
+ return s.find( infix ) != std::string::npos;
+ }
+ void toLowerInPlace( std::string& s ) {
+ std::transform( s.begin(), s.end(), s.begin(), ::tolower );
+ }
+ std::string toLower( std::string const& s ) {
+ std::string lc = s;
+ toLowerInPlace( lc );
+ return lc;
+ }
+ std::string trim( std::string const& str ) {
+ static char const* whitespaceChars = "\n\r\t ";
+ std::string::size_type start = str.find_first_not_of( whitespaceChars );
+ std::string::size_type end = str.find_last_not_of( whitespaceChars );
+
+ return start != std::string::npos ? str.substr( start, 1+end-start ) : "";
+ }
+
+ bool replaceInPlace( std::string& str, std::string const& replaceThis, std::string const& withThis ) {
+ bool replaced = false;
+ std::size_t i = str.find( replaceThis );
+ while( i != std::string::npos ) {
+ replaced = true;
+ str = str.substr( 0, i ) + withThis + str.substr( i+replaceThis.size() );
+ if( i < str.size()-withThis.size() )
+ i = str.find( replaceThis, i+withThis.size() );
+ else
+ i = std::string::npos;
+ }
+ return replaced;
+ }
+
+ pluralise::pluralise( std::size_t count, std::string const& label )
+ : m_count( count ),
+ m_label( label )
+ {}
+
+ std::ostream& operator << ( std::ostream& os, pluralise const& pluraliser ) {
+ os << pluraliser.m_count << " " << pluraliser.m_label;
+ if( pluraliser.m_count != 1 )
+ os << "s";
+ return os;
+ }
+
+ SourceLineInfo::SourceLineInfo() : line( 0 ){}
+ SourceLineInfo::SourceLineInfo( char const* _file, std::size_t _line )
+ : file( _file ),
+ line( _line )
+ {}
+ SourceLineInfo::SourceLineInfo( SourceLineInfo const& other )
+ : file( other.file ),
+ line( other.line )
+ {}
+ bool SourceLineInfo::empty() const {
+ return file.empty();
+ }
+ bool SourceLineInfo::operator == ( SourceLineInfo const& other ) const {
+ return line == other.line && file == other.file;
+ }
+ bool SourceLineInfo::operator < ( SourceLineInfo const& other ) const {
+ return line < other.line || ( line == other.line && file < other.file );
+ }
+
+ void seedRng( IConfig const& config ) {
+ if( config.rngSeed() != 0 )
+ std::srand( config.rngSeed() );
+ }
+ unsigned int rngSeed() {
+ return getCurrentContext().getConfig()->rngSeed();
+ }
+
+ std::ostream& operator << ( std::ostream& os, SourceLineInfo const& info ) {
+#ifndef __GNUG__
+ os << info.file << "(" << info.line << ")";
+#else
+ os << info.file << ":" << info.line;
+#endif
+ return os;
+ }
+
+ void throwLogicError( std::string const& message, SourceLineInfo const& locationInfo ) {
+ std::ostringstream oss;
+ oss << locationInfo << ": Internal Catch error: '" << message << "'";
+ if( alwaysTrue() )
+ throw std::logic_error( oss.str() );
+ }
+}
+
+// #included from: catch_section.hpp
+#define TWOBLUECUBES_CATCH_SECTION_HPP_INCLUDED
+
+namespace Catch {
+
+ SectionInfo::SectionInfo
+ ( SourceLineInfo const& _lineInfo,
+ std::string const& _name,
+ std::string const& _description )
+ : name( _name ),
+ description( _description ),
+ lineInfo( _lineInfo )
+ {}
+
+ Section::Section( SectionInfo const& info )
+ : m_info( info ),
+ m_sectionIncluded( getResultCapture().sectionStarted( m_info, m_assertions ) )
+ {
+ m_timer.start();
+ }
+
+ Section::~Section() {
+ if( m_sectionIncluded ) {
+ SectionEndInfo endInfo( m_info, m_assertions, m_timer.getElapsedSeconds() );
+ if( std::uncaught_exception() )
+ getResultCapture().sectionEndedEarly( endInfo );
+ else
+ getResultCapture().sectionEnded( endInfo );
+ }
+ }
+
+ // This indicates whether the section should be executed or not
+ Section::operator bool() const {
+ return m_sectionIncluded;
+ }
+
+} // end namespace Catch
+
+// #included from: catch_debugger.hpp
+#define TWOBLUECUBES_CATCH_DEBUGGER_HPP_INCLUDED
+
+#include <iostream>
+
+#ifdef CATCH_PLATFORM_MAC
+
+ #include <assert.h>
+ #include <stdbool.h>
+ #include <sys/types.h>
+ #include <unistd.h>
+ #include <sys/sysctl.h>
+
+ namespace Catch{
+
+ // The following function is taken directly from the following technical note:
+ // http://developer.apple.com/library/mac/#qa/qa2004/qa1361.html
+
+ // Returns true if the current process is being debugged (either
+ // running under the debugger or has a debugger attached post facto).
+ bool isDebuggerActive(){
+
+ int mib[4];
+ struct kinfo_proc info;
+ size_t size;
+
+ // Initialize the flags so that, if sysctl fails for some bizarre
+ // reason, we get a predictable result.
+
+ info.kp_proc.p_flag = 0;
+
+ // Initialize mib, which tells sysctl the info we want, in this case
+ // we're looking for information about a specific process ID.
+
+ mib[0] = CTL_KERN;
+ mib[1] = KERN_PROC;
+ mib[2] = KERN_PROC_PID;
+ mib[3] = getpid();
+
+ // Call sysctl.
+
+ size = sizeof(info);
+ if( sysctl(mib, sizeof(mib) / sizeof(*mib), &info, &size, CATCH_NULL, 0) != 0 ) {
+ Catch::cerr() << "\n** Call to sysctl failed - unable to determine if debugger is active **\n" << std::endl;
+ return false;
+ }
+
+ // We're being debugged if the P_TRACED flag is set.
+
+ return ( (info.kp_proc.p_flag & P_TRACED) != 0 );
+ }
+ } // namespace Catch
+
+#elif defined(_MSC_VER)
+ extern "C" __declspec(dllimport) int __stdcall IsDebuggerPresent();
+ namespace Catch {
+ bool isDebuggerActive() {
+ return IsDebuggerPresent() != 0;
+ }
+ }
+#elif defined(__MINGW32__)
+ extern "C" __declspec(dllimport) int __stdcall IsDebuggerPresent();
+ namespace Catch {
+ bool isDebuggerActive() {
+ return IsDebuggerPresent() != 0;
+ }
+ }
+#else
+ namespace Catch {
+ inline bool isDebuggerActive() { return false; }
+ }
+#endif // Platform
+
+#ifdef CATCH_PLATFORM_WINDOWS
+ extern "C" __declspec(dllimport) void __stdcall OutputDebugStringA( const char* );
+ namespace Catch {
+ void writeToDebugConsole( std::string const& text ) {
+ ::OutputDebugStringA( text.c_str() );
+ }
+ }
+#else
+ namespace Catch {
+ void writeToDebugConsole( std::string const& text ) {
+ // !TBD: Need a version for Mac/ XCode and other IDEs
+ Catch::cout() << text;
+ }
+ }
+#endif // Platform
+
+// #included from: catch_tostring.hpp
+#define TWOBLUECUBES_CATCH_TOSTRING_HPP_INCLUDED
+
+namespace Catch {
+
+namespace Detail {
+
+ const std::string unprintableString = "{?}";
+
+ namespace {
+ const int hexThreshold = 255;
+
+ struct Endianness {
+ enum Arch { Big, Little };
+
+ static Arch which() {
+ union _{
+ int asInt;
+ char asChar[sizeof (int)];
+ } u;
+
+ u.asInt = 1;
+ return ( u.asChar[sizeof(int)-1] == 1 ) ? Big : Little;
+ }
+ };
+ }
+
+ std::string rawMemoryToString( const void *object, std::size_t size )
+ {
+ // Reverse order for little endian architectures
+ int i = 0, end = static_cast<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();
+ }
+}
+
+std::string toString( std::string const& value ) {
+ std::string s = value;
+ if( getCurrentContext().getConfig()->showInvisibles() ) {
+ for(size_t i = 0; i < s.size(); ++i ) {
+ std::string subs;
+ switch( s[i] ) {
+ case '\n': subs = "\\n"; break;
+ case '\t': subs = "\\t"; break;
+ default: break;
+ }
+ if( !subs.empty() ) {
+ s = s.substr( 0, i ) + subs + s.substr( i+1 );
+ ++i;
+ }
+ }
+ }
+ return "\"" + s + "\"";
+}
+std::string toString( std::wstring const& value ) {
+
+ std::string s;
+ s.reserve( value.size() );
+ for(size_t i = 0; i < value.size(); ++i )
+ s += value[i] <= 0xff ? static_cast<char>( value[i] ) : '?';
+ return Catch::toString( s );
+}
+
+std::string toString( const char* const value ) {
+ return value ? Catch::toString( std::string( value ) ) : std::string( "{null string}" );
+}
+
+std::string toString( char* const value ) {
+ return Catch::toString( static_cast<const char*>( value ) );
+}
+
+std::string toString( const wchar_t* const value )
+{
+ return value ? Catch::toString( std::wstring(value) ) : std::string( "{null string}" );
+}
+
+std::string toString( wchar_t* const value )
+{
+ return Catch::toString( static_cast<const wchar_t*>( value ) );
+}
+
+std::string toString( int value ) {
+ std::ostringstream oss;
+ oss << value;
+ if( value > Detail::hexThreshold )
+ oss << " (0x" << std::hex << value << ")";
+ return oss.str();
+}
+
+std::string toString( unsigned long value ) {
+ std::ostringstream oss;
+ oss << value;
+ if( value > Detail::hexThreshold )
+ oss << " (0x" << std::hex << value << ")";
+ return oss.str();
+}
+
+std::string toString( unsigned int value ) {
+ return Catch::toString( static_cast<unsigned long>( value ) );
+}
+
+template<typename T>
+std::string fpToString( T value, int precision ) {
+ std::ostringstream oss;
+ oss << std::setprecision( precision )
+ << std::fixed
+ << value;
+ std::string d = oss.str();
+ std::size_t i = d.find_last_not_of( '0' );
+ if( i != std::string::npos && i != d.size()-1 ) {
+ if( d[i] == '.' )
+ i++;
+ d = d.substr( 0, i+1 );
+ }
+ return d;
+}
+
+std::string toString( const double value ) {
+ return fpToString( value, 10 );
+}
+std::string toString( const float value ) {
+ return fpToString( value, 5 ) + "f";
+}
+
+std::string toString( bool value ) {
+ return value ? "true" : "false";
+}
+
+std::string toString( char value ) {
+ return value < ' '
+ ? toString( static_cast<unsigned int>( value ) )
+ : Detail::makeString( value );
+}
+
+std::string toString( signed char value ) {
+ return toString( static_cast<char>( value ) );
+}
+
+std::string toString( unsigned char value ) {
+ return toString( static_cast<char>( value ) );
+}
+
+#ifdef CATCH_CONFIG_CPP11_LONG_LONG
+std::string toString( long long value ) {
+ std::ostringstream oss;
+ oss << value;
+ if( value > Detail::hexThreshold )
+ oss << " (0x" << std::hex << value << ")";
+ return oss.str();
+}
+std::string toString( unsigned long long value ) {
+ std::ostringstream oss;
+ oss << value;
+ if( value > Detail::hexThreshold )
+ oss << " (0x" << std::hex << value << ")";
+ return oss.str();
+}
+#endif
+
+#ifdef CATCH_CONFIG_CPP11_NULLPTR
+std::string toString( std::nullptr_t ) {
+ return "nullptr";
+}
+#endif
+
+#ifdef __OBJC__
+ std::string toString( NSString const * const& nsstring ) {
+ if( !nsstring )
+ return "nil";
+ return "@" + toString([nsstring UTF8String]);
+ }
+ std::string toString( NSString * CATCH_ARC_STRONG const& nsstring ) {
+ if( !nsstring )
+ return "nil";
+ return "@" + toString([nsstring UTF8String]);
+ }
+ std::string toString( NSObject* const& nsObject ) {
+ return toString( [nsObject description] );
+ }
+#endif
+
+} // end namespace Catch
+
+// #included from: catch_result_builder.hpp
+#define TWOBLUECUBES_CATCH_RESULT_BUILDER_HPP_INCLUDED
+
+namespace Catch {
+
+ std::string capturedExpressionWithSecondArgument( std::string const& capturedExpression, std::string const& secondArg ) {
+ return secondArg.empty() || secondArg == "\"\""
+ ? capturedExpression
+ : capturedExpression + ", " + secondArg;
+ }
+ ResultBuilder::ResultBuilder( char const* macroName,
+ SourceLineInfo const& lineInfo,
+ char const* capturedExpression,
+ ResultDisposition::Flags resultDisposition,
+ char const* secondArg )
+ : m_assertionInfo( macroName, lineInfo, capturedExpressionWithSecondArgument( capturedExpression, secondArg ), resultDisposition ),
+ m_shouldDebugBreak( false ),
+ m_shouldThrow( false )
+ {}
+
+ ResultBuilder& ResultBuilder::setResultType( ResultWas::OfType result ) {
+ m_data.resultType = result;
+ return *this;
+ }
+ ResultBuilder& ResultBuilder::setResultType( bool result ) {
+ m_data.resultType = result ? ResultWas::Ok : ResultWas::ExpressionFailed;
+ return *this;
+ }
+ ResultBuilder& ResultBuilder::setLhs( std::string const& lhs ) {
+ m_exprComponents.lhs = lhs;
+ return *this;
+ }
+ ResultBuilder& ResultBuilder::setRhs( std::string const& rhs ) {
+ m_exprComponents.rhs = rhs;
+ return *this;
+ }
+ ResultBuilder& ResultBuilder::setOp( std::string const& op ) {
+ m_exprComponents.op = op;
+ return *this;
+ }
+
+ void ResultBuilder::endExpression() {
+ m_exprComponents.testFalse = isFalseTest( m_assertionInfo.resultDisposition );
+ captureExpression();
+ }
+
+ void ResultBuilder::useActiveException( ResultDisposition::Flags resultDisposition ) {
+ m_assertionInfo.resultDisposition = resultDisposition;
+ m_stream.oss << Catch::translateActiveException();
+ captureResult( ResultWas::ThrewException );
+ }
+
+ void ResultBuilder::captureResult( ResultWas::OfType resultType ) {
+ setResultType( resultType );
+ captureExpression();
+ }
+ void ResultBuilder::captureExpectedException( std::string const& expectedMessage ) {
+ if( expectedMessage.empty() )
+ captureExpectedException( Matchers::Impl::Generic::AllOf<std::string>() );
+ else
+ captureExpectedException( Matchers::Equals( expectedMessage ) );
+ }
+
+ void ResultBuilder::captureExpectedException( Matchers::Impl::Matcher<std::string> const& matcher ) {
+
+ assert( m_exprComponents.testFalse == false );
+ AssertionResultData data = m_data;
+ data.resultType = ResultWas::Ok;
+ data.reconstructedExpression = m_assertionInfo.capturedExpression;
+
+ std::string actualMessage = Catch::translateActiveException();
+ if( !matcher.match( actualMessage ) ) {
+ data.resultType = ResultWas::ExpressionFailed;
+ data.reconstructedExpression = actualMessage;
+ }
+ AssertionResult result( m_assertionInfo, data );
+ handleResult( result );
+ }
+
+ void ResultBuilder::captureExpression() {
+ AssertionResult result = build();
+ handleResult( result );
+ }
+ void ResultBuilder::handleResult( AssertionResult const& result )
+ {
+ getResultCapture().assertionEnded( result );
+
+ if( !result.isOk() ) {
+ if( getCurrentContext().getConfig()->shouldDebugBreak() )
+ m_shouldDebugBreak = true;
+ if( getCurrentContext().getRunner()->aborting() || (m_assertionInfo.resultDisposition & ResultDisposition::Normal) )
+ m_shouldThrow = true;
+ }
+ }
+ void ResultBuilder::react() {
+ if( m_shouldThrow )
+ throw Catch::TestFailureException();
+ }
+
+ bool ResultBuilder::shouldDebugBreak() const { return m_shouldDebugBreak; }
+ bool ResultBuilder::allowThrows() const { return getCurrentContext().getConfig()->allowThrows(); }
+
+ AssertionResult ResultBuilder::build() const
+ {
+ assert( m_data.resultType != ResultWas::Unknown );
+
+ AssertionResultData data = m_data;
+
+ // Flip bool results if testFalse is set
+ if( m_exprComponents.testFalse ) {
+ if( data.resultType == ResultWas::Ok )
+ data.resultType = ResultWas::ExpressionFailed;
+ else if( data.resultType == ResultWas::ExpressionFailed )
+ data.resultType = ResultWas::Ok;
+ }
+
+ data.message = m_stream.oss.str();
+ data.reconstructedExpression = reconstructExpression();
+ if( m_exprComponents.testFalse ) {
+ if( m_exprComponents.op == "" )
+ data.reconstructedExpression = "!" + data.reconstructedExpression;
+ else
+ data.reconstructedExpression = "!(" + data.reconstructedExpression + ")";
+ }
+ return AssertionResult( m_assertionInfo, data );
+ }
+ std::string ResultBuilder::reconstructExpression() const {
+ if( m_exprComponents.op == "" )
+ return m_exprComponents.lhs.empty() ? m_assertionInfo.capturedExpression : m_exprComponents.op + m_exprComponents.lhs;
+ else if( m_exprComponents.op == "matches" )
+ return m_exprComponents.lhs + " " + m_exprComponents.rhs;
+ else if( m_exprComponents.op != "!" ) {
+ if( m_exprComponents.lhs.size() + m_exprComponents.rhs.size() < 40 &&
+ m_exprComponents.lhs.find("\n") == std::string::npos &&
+ m_exprComponents.rhs.find("\n") == std::string::npos )
+ return m_exprComponents.lhs + " " + m_exprComponents.op + " " + m_exprComponents.rhs;
+ else
+ return m_exprComponents.lhs + "\n" + m_exprComponents.op + "\n" + m_exprComponents.rhs;
+ }
+ else
+ return "{can't expand - use " + m_assertionInfo.macroName + "_FALSE( " + m_assertionInfo.capturedExpression.substr(1) + " ) instead of " + m_assertionInfo.macroName + "( " + m_assertionInfo.capturedExpression + " ) for better diagnostics}";
+ }
+
+} // end namespace Catch
+
+// #included from: catch_tag_alias_registry.hpp
+#define TWOBLUECUBES_CATCH_TAG_ALIAS_REGISTRY_HPP_INCLUDED
+
+// #included from: catch_tag_alias_registry.h
+#define TWOBLUECUBES_CATCH_TAG_ALIAS_REGISTRY_H_INCLUDED
+
+#include <map>
+
+namespace Catch {
+
+ class TagAliasRegistry : public ITagAliasRegistry {
+ public:
+ virtual ~TagAliasRegistry();
+ virtual Option<TagAlias> find( std::string const& alias ) const;
+ virtual std::string expandAliases( std::string const& unexpandedTestSpec ) const;
+ void add( char const* alias, char const* tag, SourceLineInfo const& lineInfo );
+ static TagAliasRegistry& get();
+
+ private:
+ std::map<std::string, TagAlias> m_registry;
+ };
+
+} // end namespace Catch
+
+#include <map>
+#include <iostream>
+
+namespace Catch {
+
+ TagAliasRegistry::~TagAliasRegistry() {}
+
+ Option<TagAlias> TagAliasRegistry::find( std::string const& alias ) const {
+ std::map<std::string, TagAlias>::const_iterator it = m_registry.find( alias );
+ if( it != m_registry.end() )
+ return it->second;
+ else
+ return Option<TagAlias>();
+ }
+
+ std::string TagAliasRegistry::expandAliases( std::string const& unexpandedTestSpec ) const {
+ std::string expandedTestSpec = unexpandedTestSpec;
+ for( std::map<std::string, TagAlias>::const_iterator it = m_registry.begin(), itEnd = m_registry.end();
+ it != itEnd;
+ ++it ) {
+ std::size_t pos = expandedTestSpec.find( it->first );
+ if( pos != std::string::npos ) {
+ expandedTestSpec = expandedTestSpec.substr( 0, pos ) +
+ it->second.tag +
+ expandedTestSpec.substr( pos + it->first.size() );
+ }
+ }
+ return expandedTestSpec;
+ }
+
+ void TagAliasRegistry::add( char const* alias, char const* tag, SourceLineInfo const& lineInfo ) {
+
+ if( !startsWith( alias, "[@" ) || !endsWith( alias, "]" ) ) {
+ std::ostringstream oss;
+ oss << "error: tag alias, \"" << alias << "\" is not of the form [@alias name].\n" << lineInfo;
+ throw std::domain_error( oss.str().c_str() );
+ }
+ if( !m_registry.insert( std::make_pair( alias, TagAlias( tag, lineInfo ) ) ).second ) {
+ std::ostringstream oss;
+ oss << "error: tag alias, \"" << alias << "\" already registered.\n"
+ << "\tFirst seen at " << find(alias)->lineInfo << "\n"
+ << "\tRedefined at " << lineInfo;
+ throw std::domain_error( oss.str().c_str() );
+ }
+ }
+
+ TagAliasRegistry& TagAliasRegistry::get() {
+ static TagAliasRegistry instance;
+ return instance;
+
+ }
+
+ ITagAliasRegistry::~ITagAliasRegistry() {}
+ ITagAliasRegistry const& ITagAliasRegistry::get() { return TagAliasRegistry::get(); }
+
+ RegistrarForTagAliases::RegistrarForTagAliases( char const* alias, char const* tag, SourceLineInfo const& lineInfo ) {
+ try {
+ TagAliasRegistry::get().add( alias, tag, lineInfo );
+ }
+ catch( std::exception& ex ) {
+ Colour colourGuard( Colour::Red );
+ Catch::cerr() << ex.what() << std::endl;
+ exit(1);
+ }
+ }
+
+} // end namespace Catch
+
+// #included from: ../reporters/catch_reporter_multi.hpp
+#define TWOBLUECUBES_CATCH_REPORTER_MULTI_HPP_INCLUDED
+
+namespace Catch {
+
+class MultipleReporters : public SharedImpl<IStreamingReporter> {
+ typedef std::vector<Ptr<IStreamingReporter> > Reporters;
+ Reporters m_reporters;
+
+public:
+ void add( Ptr<IStreamingReporter> const& reporter ) {
+ m_reporters.push_back( reporter );
+ }
+
+public: // IStreamingReporter
+
+ virtual ReporterPreferences getPreferences() const CATCH_OVERRIDE {
+ return m_reporters[0]->getPreferences();
+ }
+
+ virtual void noMatchingTestCases( std::string const& spec ) CATCH_OVERRIDE {
+ for( Reporters::const_iterator it = m_reporters.begin(), itEnd = m_reporters.end();
+ it != itEnd;
+ ++it )
+ (*it)->noMatchingTestCases( spec );
+ }
+
+ virtual void testRunStarting( TestRunInfo const& testRunInfo ) CATCH_OVERRIDE {
+ for( Reporters::const_iterator it = m_reporters.begin(), itEnd = m_reporters.end();
+ it != itEnd;
+ ++it )
+ (*it)->testRunStarting( testRunInfo );
+ }
+
+ virtual void testGroupStarting( GroupInfo const& groupInfo ) CATCH_OVERRIDE {
+ for( Reporters::const_iterator it = m_reporters.begin(), itEnd = m_reporters.end();
+ it != itEnd;
+ ++it )
+ (*it)->testGroupStarting( groupInfo );
+ }
+
+ virtual void testCaseStarting( TestCaseInfo const& testInfo ) CATCH_OVERRIDE {
+ for( Reporters::const_iterator it = m_reporters.begin(), itEnd = m_reporters.end();
+ it != itEnd;
+ ++it )
+ (*it)->testCaseStarting( testInfo );
+ }
+
+ virtual void sectionStarting( SectionInfo const& sectionInfo ) CATCH_OVERRIDE {
+ for( Reporters::const_iterator it = m_reporters.begin(), itEnd = m_reporters.end();
+ it != itEnd;
+ ++it )
+ (*it)->sectionStarting( sectionInfo );
+ }
+
+ virtual void assertionStarting( AssertionInfo const& assertionInfo ) CATCH_OVERRIDE {
+ for( Reporters::const_iterator it = m_reporters.begin(), itEnd = m_reporters.end();
+ it != itEnd;
+ ++it )
+ (*it)->assertionStarting( assertionInfo );
+ }
+
+ // The return value indicates if the messages buffer should be cleared:
+ virtual bool assertionEnded( AssertionStats const& assertionStats ) CATCH_OVERRIDE {
+ bool clearBuffer = false;
+ for( Reporters::const_iterator it = m_reporters.begin(), itEnd = m_reporters.end();
+ it != itEnd;
+ ++it )
+ clearBuffer |= (*it)->assertionEnded( assertionStats );
+ return clearBuffer;
+ }
+
+ virtual void sectionEnded( SectionStats const& sectionStats ) CATCH_OVERRIDE {
+ for( Reporters::const_iterator it = m_reporters.begin(), itEnd = m_reporters.end();
+ it != itEnd;
+ ++it )
+ (*it)->sectionEnded( sectionStats );
+ }
+
+ virtual void testCaseEnded( TestCaseStats const& testCaseStats ) CATCH_OVERRIDE {
+ for( Reporters::const_iterator it = m_reporters.begin(), itEnd = m_reporters.end();
+ it != itEnd;
+ ++it )
+ (*it)->testCaseEnded( testCaseStats );
+ }
+
+ virtual void testGroupEnded( TestGroupStats const& testGroupStats ) CATCH_OVERRIDE {
+ for( Reporters::const_iterator it = m_reporters.begin(), itEnd = m_reporters.end();
+ it != itEnd;
+ ++it )
+ (*it)->testGroupEnded( testGroupStats );
+ }
+
+ virtual void testRunEnded( TestRunStats const& testRunStats ) CATCH_OVERRIDE {
+ for( Reporters::const_iterator it = m_reporters.begin(), itEnd = m_reporters.end();
+ it != itEnd;
+ ++it )
+ (*it)->testRunEnded( testRunStats );
+ }
+
+ virtual void skipTest( TestCaseInfo const& testInfo ) CATCH_OVERRIDE {
+ for( Reporters::const_iterator it = m_reporters.begin(), itEnd = m_reporters.end();
+ it != itEnd;
+ ++it )
+ (*it)->skipTest( testInfo );
+ }
+
+ virtual MultipleReporters* tryAsMulti() CATCH_OVERRIDE {
+ return this;
+ }
+
+};
+
+Ptr<IStreamingReporter> addReporter( Ptr<IStreamingReporter> const& existingReporter, Ptr<IStreamingReporter> const& additionalReporter ) {
+ Ptr<IStreamingReporter> resultingReporter;
+
+ if( existingReporter ) {
+ MultipleReporters* multi = existingReporter->tryAsMulti();
+ if( !multi ) {
+ multi = new MultipleReporters;
+ resultingReporter = Ptr<IStreamingReporter>( multi );
+ if( existingReporter )
+ multi->add( existingReporter );
+ }
+ else
+ resultingReporter = existingReporter;
+ multi->add( additionalReporter );
+ }
+ else
+ resultingReporter = additionalReporter;
+
+ return resultingReporter;
+}
+
+} // end namespace Catch
+
+// #included from: ../reporters/catch_reporter_xml.hpp
+#define TWOBLUECUBES_CATCH_REPORTER_XML_HPP_INCLUDED
+
+// #included from: catch_reporter_bases.hpp
+#define TWOBLUECUBES_CATCH_REPORTER_BASES_HPP_INCLUDED
+
+#include <cstring>
+
+namespace Catch {
+
+ struct StreamingReporterBase : SharedImpl<IStreamingReporter> {
+
+ StreamingReporterBase( ReporterConfig const& _config )
+ : m_config( _config.fullConfig() ),
+ stream( _config.stream() )
+ {
+ m_reporterPrefs.shouldRedirectStdOut = false;
+ }
+
+ virtual ReporterPreferences getPreferences() const CATCH_OVERRIDE {
+ return m_reporterPrefs;
+ }
+
+ virtual ~StreamingReporterBase() CATCH_OVERRIDE;
+
+ virtual void noMatchingTestCases( std::string const& ) CATCH_OVERRIDE {}
+
+ virtual void testRunStarting( TestRunInfo const& _testRunInfo ) CATCH_OVERRIDE {
+ currentTestRunInfo = _testRunInfo;
+ }
+ virtual void testGroupStarting( GroupInfo const& _groupInfo ) CATCH_OVERRIDE {
+ currentGroupInfo = _groupInfo;
+ }
+
+ virtual void testCaseStarting( TestCaseInfo const& _testInfo ) CATCH_OVERRIDE {
+ currentTestCaseInfo = _testInfo;
+ }
+ virtual void sectionStarting( SectionInfo const& _sectionInfo ) CATCH_OVERRIDE {
+ m_sectionStack.push_back( _sectionInfo );
+ }
+
+ virtual void sectionEnded( SectionStats const& /* _sectionStats */ ) CATCH_OVERRIDE {
+ m_sectionStack.pop_back();
+ }
+ virtual void testCaseEnded( TestCaseStats const& /* _testCaseStats */ ) CATCH_OVERRIDE {
+ currentTestCaseInfo.reset();
+ }
+ virtual void testGroupEnded( TestGroupStats const& /* _testGroupStats */ ) CATCH_OVERRIDE {
+ currentGroupInfo.reset();
+ }
+ virtual void testRunEnded( TestRunStats const& /* _testRunStats */ ) CATCH_OVERRIDE {
+ currentTestCaseInfo.reset();
+ currentGroupInfo.reset();
+ currentTestRunInfo.reset();
+ }
+
+ virtual void skipTest( TestCaseInfo const& ) CATCH_OVERRIDE {
+ // Don't do anything with this by default.
+ // It can optionally be overridden in the derived class.
+ }
+
+ Ptr<IConfig const> m_config;
+ std::ostream& stream;
+
+ LazyStat<TestRunInfo> currentTestRunInfo;
+ LazyStat<GroupInfo> currentGroupInfo;
+ LazyStat<TestCaseInfo> currentTestCaseInfo;
+
+ std::vector<SectionInfo> m_sectionStack;
+ ReporterPreferences m_reporterPrefs;
+ };
+
+ struct CumulativeReporterBase : SharedImpl<IStreamingReporter> {
+ template<typename T, typename ChildNodeT>
+ struct Node : SharedImpl<> {
+ explicit Node( T const& _value ) : value( _value ) {}
+ virtual ~Node() {}
+
+ typedef std::vector<Ptr<ChildNodeT> > ChildNodes;
+ T value;
+ ChildNodes children;
+ };
+ struct SectionNode : SharedImpl<> {
+ explicit SectionNode( SectionStats const& _stats ) : stats( _stats ) {}
+ virtual ~SectionNode();
+
+ bool operator == ( SectionNode const& other ) const {
+ return stats.sectionInfo.lineInfo == other.stats.sectionInfo.lineInfo;
+ }
+ bool operator == ( Ptr<SectionNode> const& other ) const {
+ return operator==( *other );
+ }
+
+ SectionStats stats;
+ typedef std::vector<Ptr<SectionNode> > ChildSections;
+ typedef std::vector<AssertionStats> Assertions;
+ ChildSections childSections;
+ Assertions assertions;
+ std::string stdOut;
+ std::string stdErr;
+ };
+
+ struct BySectionInfo {
+ BySectionInfo( SectionInfo const& other ) : m_other( other ) {}
+ BySectionInfo( BySectionInfo const& other ) : m_other( other.m_other ) {}
+ bool operator() ( Ptr<SectionNode> const& node ) const {
+ return node->stats.sectionInfo.lineInfo == m_other.lineInfo;
+ }
+ private:
+ void operator=( BySectionInfo const& );
+ SectionInfo const& m_other;
+ };
+
+ typedef Node<TestCaseStats, SectionNode> TestCaseNode;
+ typedef Node<TestGroupStats, TestCaseNode> TestGroupNode;
+ typedef Node<TestRunStats, TestGroupNode> TestRunNode;
+
+ CumulativeReporterBase( ReporterConfig const& _config )
+ : m_config( _config.fullConfig() ),
+ stream( _config.stream() )
+ {
+ m_reporterPrefs.shouldRedirectStdOut = false;
+ }
+ ~CumulativeReporterBase();
+
+ virtual ReporterPreferences getPreferences() const CATCH_OVERRIDE {
+ return m_reporterPrefs;
+ }
+
+ virtual void testRunStarting( TestRunInfo const& ) CATCH_OVERRIDE {}
+ virtual void testGroupStarting( GroupInfo const& ) CATCH_OVERRIDE {}
+
+ virtual void testCaseStarting( TestCaseInfo const& ) CATCH_OVERRIDE {}
+
+ virtual void sectionStarting( SectionInfo const& sectionInfo ) CATCH_OVERRIDE {
+ SectionStats incompleteStats( sectionInfo, Counts(), 0, false );
+ Ptr<SectionNode> node;
+ if( m_sectionStack.empty() ) {
+ if( !m_rootSection )
+ m_rootSection = new SectionNode( incompleteStats );
+ node = m_rootSection;
+ }
+ else {
+ SectionNode& parentNode = *m_sectionStack.back();
+ SectionNode::ChildSections::const_iterator it =
+ std::find_if( parentNode.childSections.begin(),
+ parentNode.childSections.end(),
+ BySectionInfo( sectionInfo ) );
+ if( it == parentNode.childSections.end() ) {
+ node = new SectionNode( incompleteStats );
+ parentNode.childSections.push_back( node );
+ }
+ else
+ node = *it;
+ }
+ m_sectionStack.push_back( node );
+ m_deepestSection = node;
+ }
+
+ virtual void assertionStarting( AssertionInfo const& ) CATCH_OVERRIDE {}
+
+ virtual bool assertionEnded( AssertionStats const& assertionStats ) CATCH_OVERRIDE {
+ assert( !m_sectionStack.empty() );
+ SectionNode& sectionNode = *m_sectionStack.back();
+ sectionNode.assertions.push_back( assertionStats );
+ return true;
+ }
+ virtual void sectionEnded( SectionStats const& sectionStats ) CATCH_OVERRIDE {
+ assert( !m_sectionStack.empty() );
+ SectionNode& node = *m_sectionStack.back();
+ node.stats = sectionStats;
+ m_sectionStack.pop_back();
+ }
+ virtual void testCaseEnded( TestCaseStats const& testCaseStats ) CATCH_OVERRIDE {
+ Ptr<TestCaseNode> node = new TestCaseNode( testCaseStats );
+ assert( m_sectionStack.size() == 0 );
+ node->children.push_back( m_rootSection );
+ m_testCases.push_back( node );
+ m_rootSection.reset();
+
+ assert( m_deepestSection );
+ m_deepestSection->stdOut = testCaseStats.stdOut;
+ m_deepestSection->stdErr = testCaseStats.stdErr;
+ }
+ virtual void testGroupEnded( TestGroupStats const& testGroupStats ) CATCH_OVERRIDE {
+ Ptr<TestGroupNode> node = new TestGroupNode( testGroupStats );
+ node->children.swap( m_testCases );
+ m_testGroups.push_back( node );
+ }
+ virtual void testRunEnded( TestRunStats const& testRunStats ) CATCH_OVERRIDE {
+ Ptr<TestRunNode> node = new TestRunNode( testRunStats );
+ node->children.swap( m_testGroups );
+ m_testRuns.push_back( node );
+ testRunEndedCumulative();
+ }
+ virtual void testRunEndedCumulative() = 0;
+
+ virtual void skipTest( TestCaseInfo const& ) CATCH_OVERRIDE {}
+
+ Ptr<IConfig const> m_config;
+ std::ostream& stream;
+ std::vector<AssertionStats> m_assertions;
+ std::vector<std::vector<Ptr<SectionNode> > > m_sections;
+ std::vector<Ptr<TestCaseNode> > m_testCases;
+ std::vector<Ptr<TestGroupNode> > m_testGroups;
+
+ std::vector<Ptr<TestRunNode> > m_testRuns;
+
+ Ptr<SectionNode> m_rootSection;
+ Ptr<SectionNode> m_deepestSection;
+ std::vector<Ptr<SectionNode> > m_sectionStack;
+ ReporterPreferences m_reporterPrefs;
+
+ };
+
+ template<char C>
+ char const* getLineOfChars() {
+ static char line[CATCH_CONFIG_CONSOLE_WIDTH] = {0};
+ if( !*line ) {
+ memset( line, C, CATCH_CONFIG_CONSOLE_WIDTH-1 );
+ line[CATCH_CONFIG_CONSOLE_WIDTH-1] = 0;
+ }
+ return line;
+ }
+
+ struct TestEventListenerBase : StreamingReporterBase {
+ TestEventListenerBase( ReporterConfig const& _config )
+ : StreamingReporterBase( _config )
+ {}
+
+ virtual void assertionStarting( AssertionInfo const& ) CATCH_OVERRIDE {}
+ virtual bool assertionEnded( AssertionStats const& ) CATCH_OVERRIDE {
+ return false;
+ }
+ };
+
+} // end namespace Catch
+
+// #included from: ../internal/catch_reporter_registrars.hpp
+#define TWOBLUECUBES_CATCH_REPORTER_REGISTRARS_HPP_INCLUDED
+
+namespace Catch {
+
+ template<typename T>
+ class LegacyReporterRegistrar {
+
+ class ReporterFactory : public IReporterFactory {
+ virtual IStreamingReporter* create( ReporterConfig const& config ) const {
+ return new LegacyReporterAdapter( new T( config ) );
+ }
+
+ virtual std::string getDescription() const {
+ return T::getDescription();
+ }
+ };
+
+ public:
+
+ LegacyReporterRegistrar( std::string const& name ) {
+ getMutableRegistryHub().registerReporter( name, new ReporterFactory() );
+ }
+ };
+
+ template<typename T>
+ class ReporterRegistrar {
+
+ class ReporterFactory : public SharedImpl<IReporterFactory> {
+
+ // *** Please Note ***:
+ // - If you end up here looking at a compiler error because it's trying to register
+ // your custom reporter class be aware that the native reporter interface has changed
+ // to IStreamingReporter. The "legacy" interface, IReporter, is still supported via
+ // an adapter. Just use REGISTER_LEGACY_REPORTER to take advantage of the adapter.
+ // However please consider updating to the new interface as the old one is now
+ // deprecated and will probably be removed quite soon!
+ // Please contact me via github if you have any questions at all about this.
+ // In fact, ideally, please contact me anyway to let me know you've hit this - as I have
+ // no idea who is actually using custom reporters at all (possibly no-one!).
+ // The new interface is designed to minimise exposure to interface changes in the future.
+ virtual IStreamingReporter* create( ReporterConfig const& config ) const {
+ return new T( config );
+ }
+
+ virtual std::string getDescription() const {
+ return T::getDescription();
+ }
+ };
+
+ public:
+
+ ReporterRegistrar( std::string const& name ) {
+ getMutableRegistryHub().registerReporter( name, new ReporterFactory() );
+ }
+ };
+
+ template<typename T>
+ class ListenerRegistrar {
+
+ class ListenerFactory : public SharedImpl<IReporterFactory> {
+
+ virtual IStreamingReporter* create( ReporterConfig const& config ) const {
+ return new T( config );
+ }
+ virtual std::string getDescription() const {
+ return "";
+ }
+ };
+
+ public:
+
+ ListenerRegistrar() {
+ getMutableRegistryHub().registerListener( new ListenerFactory() );
+ }
+ };
+}
+
+#define INTERNAL_CATCH_REGISTER_LEGACY_REPORTER( name, reporterType ) \
+ namespace{ Catch::LegacyReporterRegistrar<reporterType> catch_internal_RegistrarFor##reporterType( name ); }
+
+#define INTERNAL_CATCH_REGISTER_REPORTER( name, reporterType ) \
+ namespace{ Catch::ReporterRegistrar<reporterType> catch_internal_RegistrarFor##reporterType( name ); }
+
+#define INTERNAL_CATCH_REGISTER_LISTENER( listenerType ) \
+ namespace{ Catch::ListenerRegistrar<listenerType> catch_internal_RegistrarFor##listenerType; }
+
+// #included from: ../internal/catch_xmlwriter.hpp
+#define TWOBLUECUBES_CATCH_XMLWRITER_HPP_INCLUDED
+
+#include <sstream>
+#include <string>
+#include <vector>
+#include <iomanip>
+
+namespace Catch {
+
+ class XmlEncode {
+ public:
+ enum ForWhat { ForTextNodes, ForAttributes };
+
+ XmlEncode( std::string const& str, ForWhat forWhat = ForTextNodes )
+ : m_str( str ),
+ m_forWhat( forWhat )
+ {}
+
+ void encodeTo( std::ostream& os ) const {
+
+ // Apostrophe escaping not necessary if we always use " to write attributes
+ // (see: http://www.w3.org/TR/xml/#syntax)
+
+ for( std::size_t i = 0; i < m_str.size(); ++ i ) {
+ char c = m_str[i];
+ switch( c ) {
+ case '<': os << "&lt;"; break;
+ case '&': os << "&amp;"; break;
+
+ case '>':
+ // See: http://www.w3.org/TR/xml/#syntax
+ if( i > 2 && m_str[i-1] == ']' && m_str[i-2] == ']' )
+ os << "&gt;";
+ else
+ os << c;
+ break;
+
+ case '\"':
+ if( m_forWhat == ForAttributes )
+ os << "&quot;";
+ else
+ os << c;
+ break;
+
+ default:
+ // Escape control chars - based on contribution by @espenalb in PR #465
+ if ( ( c < '\x09' ) || ( c > '\x0D' && c < '\x20') || c=='\x7F' )
+ os << "&#x" << std::uppercase << std::hex << static_cast<int>( c );
+ else
+ os << c;
+ }
+ }
+ }
+
+ friend std::ostream& operator << ( std::ostream& os, XmlEncode const& xmlEncode ) {
+ xmlEncode.encodeTo( os );
+ return os;
+ }
+
+ private:
+ std::string m_str;
+ ForWhat m_forWhat;
+ };
+
+ class XmlWriter {
+ public:
+
+ class ScopedElement {
+ public:
+ ScopedElement( XmlWriter* writer )
+ : m_writer( writer )
+ {}
+
+ ScopedElement( ScopedElement const& other )
+ : m_writer( other.m_writer ){
+ other.m_writer = CATCH_NULL;
+ }
+
+ ~ScopedElement() {
+ if( m_writer )
+ m_writer->endElement();
+ }
+
+ ScopedElement& writeText( std::string const& text, bool indent = true ) {
+ m_writer->writeText( text, indent );
+ return *this;
+ }
+
+ template<typename T>
+ ScopedElement& writeAttribute( std::string const& name, T const& attribute ) {
+ m_writer->writeAttribute( name, attribute );
+ return *this;
+ }
+
+ private:
+ mutable XmlWriter* m_writer;
+ };
+
+ XmlWriter()
+ : m_tagIsOpen( false ),
+ m_needsNewline( false ),
+ m_os( &Catch::cout() )
+ {}
+
+ XmlWriter( std::ostream& os )
+ : m_tagIsOpen( false ),
+ m_needsNewline( false ),
+ m_os( &os )
+ {}
+
+ ~XmlWriter() {
+ while( !m_tags.empty() )
+ endElement();
+ }
+
+ XmlWriter& startElement( std::string const& name ) {
+ ensureTagClosed();
+ newlineIfNecessary();
+ stream() << m_indent << "<" << name;
+ m_tags.push_back( name );
+ m_indent += " ";
+ m_tagIsOpen = true;
+ return *this;
+ }
+
+ ScopedElement scopedElement( std::string const& name ) {
+ ScopedElement scoped( this );
+ startElement( name );
+ return scoped;
+ }
+
+ XmlWriter& endElement() {
+ newlineIfNecessary();
+ m_indent = m_indent.substr( 0, m_indent.size()-2 );
+ if( m_tagIsOpen ) {
+ stream() << "/>\n";
+ m_tagIsOpen = false;
+ }
+ else {
+ stream() << m_indent << "</" << m_tags.back() << ">\n";
+ }
+ m_tags.pop_back();
+ return *this;
+ }
+
+ XmlWriter& writeAttribute( std::string const& name, std::string const& attribute ) {
+ if( !name.empty() && !attribute.empty() )
+ stream() << " " << name << "=\"" << XmlEncode( attribute, XmlEncode::ForAttributes ) << "\"";
+ return *this;
+ }
+
+ XmlWriter& writeAttribute( std::string const& name, bool attribute ) {
+ stream() << " " << name << "=\"" << ( attribute ? "true" : "false" ) << "\"";
+ return *this;
+ }
+
+ template<typename T>
+ XmlWriter& writeAttribute( std::string const& name, T const& attribute ) {
+ std::ostringstream oss;
+ oss << attribute;
+ return writeAttribute( name, oss.str() );
+ }
+
+ XmlWriter& writeText( std::string const& text, bool indent = true ) {
+ if( !text.empty() ){
+ bool tagWasOpen = m_tagIsOpen;
+ ensureTagClosed();
+ if( tagWasOpen && indent )
+ stream() << m_indent;
+ stream() << XmlEncode( text );
+ m_needsNewline = true;
+ }
+ return *this;
+ }
+
+ XmlWriter& writeComment( std::string const& text ) {
+ ensureTagClosed();
+ stream() << m_indent << "<!--" << text << "-->";
+ m_needsNewline = true;
+ return *this;
+ }
+
+ XmlWriter& writeBlankLine() {
+ ensureTagClosed();
+ stream() << "\n";
+ return *this;
+ }
+
+ void setStream( std::ostream& os ) {
+ m_os = &os;
+ }
+
+ private:
+ XmlWriter( XmlWriter const& );
+ void operator=( XmlWriter const& );
+
+ std::ostream& stream() {
+ return *m_os;
+ }
+
+ void ensureTagClosed() {
+ if( m_tagIsOpen ) {
+ stream() << ">\n";
+ m_tagIsOpen = false;
+ }
+ }
+
+ void newlineIfNecessary() {
+ if( m_needsNewline ) {
+ stream() << "\n";
+ m_needsNewline = false;
+ }
+ }
+
+ bool m_tagIsOpen;
+ bool m_needsNewline;
+ std::vector<std::string> m_tags;
+ std::string m_indent;
+ std::ostream* m_os;
+ };
+
+}
+// #included from: catch_reenable_warnings.h
+
+#define TWOBLUECUBES_CATCH_REENABLE_WARNINGS_H_INCLUDED
+
+#ifdef __clang__
+# ifdef __ICC // icpc defines the __clang__ macro
+# pragma warning(pop)
+# else
+# pragma clang diagnostic pop
+# endif
+#elif defined __GNUC__
+# pragma GCC diagnostic pop
+#endif
+
+
+namespace Catch {
+ class XmlReporter : public StreamingReporterBase {
+ public:
+ XmlReporter( ReporterConfig const& _config )
+ : StreamingReporterBase( _config ),
+ m_sectionDepth( 0 )
+ {
+ m_reporterPrefs.shouldRedirectStdOut = true;
+ }
+
+ virtual ~XmlReporter() CATCH_OVERRIDE;
+
+ static std::string getDescription() {
+ return "Reports test results as an XML document";
+ }
+
+ public: // StreamingReporterBase
+
+ virtual void noMatchingTestCases( std::string const& s ) CATCH_OVERRIDE {
+ StreamingReporterBase::noMatchingTestCases( s );
+ }
+
+ virtual void testRunStarting( TestRunInfo const& testInfo ) CATCH_OVERRIDE {
+ StreamingReporterBase::testRunStarting( testInfo );
+ m_xml.setStream( stream );
+ m_xml.startElement( "Catch" );
+ if( !m_config->name().empty() )
+ m_xml.writeAttribute( "name", m_config->name() );
+ }
+
+ virtual void testGroupStarting( GroupInfo const& groupInfo ) CATCH_OVERRIDE {
+ StreamingReporterBase::testGroupStarting( groupInfo );
+ m_xml.startElement( "Group" )
+ .writeAttribute( "name", groupInfo.name );
+ }
+
+ virtual void testCaseStarting( TestCaseInfo const& testInfo ) CATCH_OVERRIDE {
+ StreamingReporterBase::testCaseStarting(testInfo);
+ m_xml.startElement( "TestCase" ).writeAttribute( "name", trim( testInfo.name ) );
+
+ if ( m_config->showDurations() == ShowDurations::Always )
+ m_testCaseTimer.start();
+ }
+
+ virtual void sectionStarting( SectionInfo const& sectionInfo ) CATCH_OVERRIDE {
+ StreamingReporterBase::sectionStarting( sectionInfo );
+ if( m_sectionDepth++ > 0 ) {
+ m_xml.startElement( "Section" )
+ .writeAttribute( "name", trim( sectionInfo.name ) )
+ .writeAttribute( "description", sectionInfo.description );
+ }
+ }
+
+ virtual void assertionStarting( AssertionInfo const& ) CATCH_OVERRIDE { }
+
+ virtual bool assertionEnded( AssertionStats const& assertionStats ) CATCH_OVERRIDE {
+ const AssertionResult& assertionResult = assertionStats.assertionResult;
+
+ // Print any info messages in <Info> tags.
+ if( assertionStats.assertionResult.getResultType() != ResultWas::Ok ) {
+ for( std::vector<MessageInfo>::const_iterator it = assertionStats.infoMessages.begin(), itEnd = assertionStats.infoMessages.end();
+ it != itEnd;
+ ++it ) {
+ if( it->type == ResultWas::Info ) {
+ m_xml.scopedElement( "Info" )
+ .writeText( it->message );
+ } else if ( it->type == ResultWas::Warning ) {
+ m_xml.scopedElement( "Warning" )
+ .writeText( it->message );
+ }
+ }
+ }
+
+ // Drop out if result was successful but we're not printing them.
+ if( !m_config->includeSuccessfulResults() && isOk(assertionResult.getResultType()) )
+ return true;
+
+ // Print the expression if there is one.
+ if( assertionResult.hasExpression() ) {
+ m_xml.startElement( "Expression" )
+ .writeAttribute( "success", assertionResult.succeeded() )
+ .writeAttribute( "type", assertionResult.getTestMacroName() )
+ .writeAttribute( "filename", assertionResult.getSourceInfo().file )
+ .writeAttribute( "line", assertionResult.getSourceInfo().line );
+
+ m_xml.scopedElement( "Original" )
+ .writeText( assertionResult.getExpression() );
+ m_xml.scopedElement( "Expanded" )
+ .writeText( assertionResult.getExpandedExpression() );
+ }
+
+ // And... Print a result applicable to each result type.
+ switch( assertionResult.getResultType() ) {
+ case ResultWas::ThrewException:
+ m_xml.scopedElement( "Exception" )
+ .writeAttribute( "filename", assertionResult.getSourceInfo().file )
+ .writeAttribute( "line", assertionResult.getSourceInfo().line )
+ .writeText( assertionResult.getMessage() );
+ break;
+ case ResultWas::FatalErrorCondition:
+ m_xml.scopedElement( "Fatal Error Condition" )
+ .writeAttribute( "filename", assertionResult.getSourceInfo().file )
+ .writeAttribute( "line", assertionResult.getSourceInfo().line )
+ .writeText( assertionResult.getMessage() );
+ break;
+ case ResultWas::Info:
+ m_xml.scopedElement( "Info" )
+ .writeText( assertionResult.getMessage() );
+ break;
+ case ResultWas::Warning:
+ // Warning will already have been written
+ break;
+ case ResultWas::ExplicitFailure:
+ m_xml.scopedElement( "Failure" )
+ .writeText( assertionResult.getMessage() );
+ break;
+ default:
+ break;
+ }
+
+ if( assertionResult.hasExpression() )
+ m_xml.endElement();
+
+ return true;
+ }
+
+ virtual void sectionEnded( SectionStats const& sectionStats ) CATCH_OVERRIDE {
+ StreamingReporterBase::sectionEnded( sectionStats );
+ if( --m_sectionDepth > 0 ) {
+ XmlWriter::ScopedElement e = m_xml.scopedElement( "OverallResults" );
+ e.writeAttribute( "successes", sectionStats.assertions.passed );
+ e.writeAttribute( "failures", sectionStats.assertions.failed );
+ e.writeAttribute( "expectedFailures", sectionStats.assertions.failedButOk );
+
+ if ( m_config->showDurations() == ShowDurations::Always )
+ e.writeAttribute( "durationInSeconds", sectionStats.durationInSeconds );
+
+ m_xml.endElement();
+ }
+ }
+
+ virtual void testCaseEnded( TestCaseStats const& testCaseStats ) CATCH_OVERRIDE {
+ StreamingReporterBase::testCaseEnded( testCaseStats );
+ XmlWriter::ScopedElement e = m_xml.scopedElement( "OverallResult" );
+ e.writeAttribute( "success", testCaseStats.totals.assertions.allOk() );
+
+ if ( m_config->showDurations() == ShowDurations::Always )
+ e.writeAttribute( "durationInSeconds", m_testCaseTimer.getElapsedSeconds() );
+
+ m_xml.endElement();
+ }
+
+ virtual void testGroupEnded( TestGroupStats const& testGroupStats ) CATCH_OVERRIDE {
+ StreamingReporterBase::testGroupEnded( testGroupStats );
+ // TODO: Check testGroupStats.aborting and act accordingly.
+ m_xml.scopedElement( "OverallResults" )
+ .writeAttribute( "successes", testGroupStats.totals.assertions.passed )
+ .writeAttribute( "failures", testGroupStats.totals.assertions.failed )
+ .writeAttribute( "expectedFailures", testGroupStats.totals.assertions.failedButOk );
+ m_xml.endElement();
+ }
+
+ virtual void testRunEnded( TestRunStats const& testRunStats ) CATCH_OVERRIDE {
+ StreamingReporterBase::testRunEnded( testRunStats );
+ m_xml.scopedElement( "OverallResults" )
+ .writeAttribute( "successes", testRunStats.totals.assertions.passed )
+ .writeAttribute( "failures", testRunStats.totals.assertions.failed )
+ .writeAttribute( "expectedFailures", testRunStats.totals.assertions.failedButOk );
+ m_xml.endElement();
+ }
+
+ private:
+ Timer m_testCaseTimer;
+ XmlWriter m_xml;
+ int m_sectionDepth;
+ };
+
+ INTERNAL_CATCH_REGISTER_REPORTER( "xml", XmlReporter )
+
+} // end namespace Catch
+
+// #included from: ../reporters/catch_reporter_junit.hpp
+#define TWOBLUECUBES_CATCH_REPORTER_JUNIT_HPP_INCLUDED
+
+#include <assert.h>
+
+namespace Catch {
+
+ class JunitReporter : public CumulativeReporterBase {
+ public:
+ JunitReporter( ReporterConfig const& _config )
+ : CumulativeReporterBase( _config ),
+ xml( _config.stream() )
+ {
+ m_reporterPrefs.shouldRedirectStdOut = true;
+ }
+
+ virtual ~JunitReporter() CATCH_OVERRIDE;
+
+ static std::string getDescription() {
+ return "Reports test results in an XML format that looks like Ant's junitreport target";
+ }
+
+ virtual void noMatchingTestCases( std::string const& /*spec*/ ) CATCH_OVERRIDE {}
+
+ virtual void testRunStarting( TestRunInfo const& runInfo ) CATCH_OVERRIDE {
+ CumulativeReporterBase::testRunStarting( runInfo );
+ xml.startElement( "testsuites" );
+ }
+
+ virtual void testGroupStarting( GroupInfo const& groupInfo ) CATCH_OVERRIDE {
+ suiteTimer.start();
+ stdOutForSuite.str("");
+ stdErrForSuite.str("");
+ unexpectedExceptions = 0;
+ CumulativeReporterBase::testGroupStarting( groupInfo );
+ }
+
+ virtual bool assertionEnded( AssertionStats const& assertionStats ) CATCH_OVERRIDE {
+ if( assertionStats.assertionResult.getResultType() == ResultWas::ThrewException )
+ unexpectedExceptions++;
+ return CumulativeReporterBase::assertionEnded( assertionStats );
+ }
+
+ virtual void testCaseEnded( TestCaseStats const& testCaseStats ) CATCH_OVERRIDE {
+ stdOutForSuite << testCaseStats.stdOut;
+ stdErrForSuite << testCaseStats.stdErr;
+ CumulativeReporterBase::testCaseEnded( testCaseStats );
+ }
+
+ virtual void testGroupEnded( TestGroupStats const& testGroupStats ) CATCH_OVERRIDE {
+ double suiteTime = suiteTimer.getElapsedSeconds();
+ CumulativeReporterBase::testGroupEnded( testGroupStats );
+ writeGroup( *m_testGroups.back(), suiteTime );
+ }
+
+ virtual void testRunEndedCumulative() CATCH_OVERRIDE {
+ xml.endElement();
+ }
+
+ void writeGroup( TestGroupNode const& groupNode, double suiteTime ) {
+ XmlWriter::ScopedElement e = xml.scopedElement( "testsuite" );
+ TestGroupStats const& stats = groupNode.value;
+ xml.writeAttribute( "name", stats.groupInfo.name );
+ xml.writeAttribute( "errors", unexpectedExceptions );
+ xml.writeAttribute( "failures", stats.totals.assertions.failed-unexpectedExceptions );
+ xml.writeAttribute( "tests", stats.totals.assertions.total() );
+ xml.writeAttribute( "hostname", "tbd" ); // !TBD
+ if( m_config->showDurations() == ShowDurations::Never )
+ xml.writeAttribute( "time", "" );
+ else
+ xml.writeAttribute( "time", suiteTime );
+ xml.writeAttribute( "timestamp", "tbd" ); // !TBD
+
+ // Write test cases
+ for( TestGroupNode::ChildNodes::const_iterator
+ it = groupNode.children.begin(), itEnd = groupNode.children.end();
+ it != itEnd;
+ ++it )
+ writeTestCase( **it );
+
+ xml.scopedElement( "system-out" ).writeText( trim( stdOutForSuite.str() ), false );
+ xml.scopedElement( "system-err" ).writeText( trim( stdErrForSuite.str() ), false );
+ }
+
+ void writeTestCase( TestCaseNode const& testCaseNode ) {
+ TestCaseStats const& stats = testCaseNode.value;
+
+ // All test cases have exactly one section - which represents the
+ // test case itself. That section may have 0-n nested sections
+ assert( testCaseNode.children.size() == 1 );
+ SectionNode const& rootSection = *testCaseNode.children.front();
+
+ std::string className = stats.testInfo.className;
+
+ if( className.empty() ) {
+ if( rootSection.childSections.empty() )
+ className = "global";
+ }
+ writeSection( className, "", rootSection );
+ }
+
+ void writeSection( std::string const& className,
+ std::string const& rootName,
+ SectionNode const& sectionNode ) {
+ std::string name = trim( sectionNode.stats.sectionInfo.name );
+ if( !rootName.empty() )
+ name = rootName + "/" + name;
+
+ if( !sectionNode.assertions.empty() ||
+ !sectionNode.stdOut.empty() ||
+ !sectionNode.stdErr.empty() ) {
+ XmlWriter::ScopedElement e = xml.scopedElement( "testcase" );
+ if( className.empty() ) {
+ xml.writeAttribute( "classname", name );
+ xml.writeAttribute( "name", "root" );
+ }
+ else {
+ xml.writeAttribute( "classname", className );
+ xml.writeAttribute( "name", name );
+ }
+ xml.writeAttribute( "time", Catch::toString( sectionNode.stats.durationInSeconds ) );
+
+ writeAssertions( sectionNode );
+
+ if( !sectionNode.stdOut.empty() )
+ xml.scopedElement( "system-out" ).writeText( trim( sectionNode.stdOut ), false );
+ if( !sectionNode.stdErr.empty() )
+ xml.scopedElement( "system-err" ).writeText( trim( sectionNode.stdErr ), false );
+ }
+ for( SectionNode::ChildSections::const_iterator
+ it = sectionNode.childSections.begin(),
+ itEnd = sectionNode.childSections.end();
+ it != itEnd;
+ ++it )
+ if( className.empty() )
+ writeSection( name, "", **it );
+ else
+ writeSection( className, name, **it );
+ }
+
+ void writeAssertions( SectionNode const& sectionNode ) {
+ for( SectionNode::Assertions::const_iterator
+ it = sectionNode.assertions.begin(), itEnd = sectionNode.assertions.end();
+ it != itEnd;
+ ++it )
+ writeAssertion( *it );
+ }
+ void writeAssertion( AssertionStats const& stats ) {
+ AssertionResult const& result = stats.assertionResult;
+ if( !result.isOk() ) {
+ std::string elementName;
+ switch( result.getResultType() ) {
+ case ResultWas::ThrewException:
+ case ResultWas::FatalErrorCondition:
+ elementName = "error";
+ break;
+ case ResultWas::ExplicitFailure:
+ elementName = "failure";
+ break;
+ case ResultWas::ExpressionFailed:
+ elementName = "failure";
+ break;
+ case ResultWas::DidntThrowException:
+ elementName = "failure";
+ break;
+
+ // We should never see these here:
+ case ResultWas::Info:
+ case ResultWas::Warning:
+ case ResultWas::Ok:
+ case ResultWas::Unknown:
+ case ResultWas::FailureBit:
+ case ResultWas::Exception:
+ elementName = "internalError";
+ break;
+ }
+
+ XmlWriter::ScopedElement e = xml.scopedElement( elementName );
+
+ xml.writeAttribute( "message", result.getExpandedExpression() );
+ xml.writeAttribute( "type", result.getTestMacroName() );
+
+ std::ostringstream oss;
+ if( !result.getMessage().empty() )
+ oss << result.getMessage() << "\n";
+ for( std::vector<MessageInfo>::const_iterator
+ it = stats.infoMessages.begin(),
+ itEnd = stats.infoMessages.end();
+ it != itEnd;
+ ++it )
+ if( it->type == ResultWas::Info )
+ oss << it->message << "\n";
+
+ oss << "at " << result.getSourceInfo();
+ xml.writeText( oss.str(), false );
+ }
+ }
+
+ XmlWriter xml;
+ Timer suiteTimer;
+ std::ostringstream stdOutForSuite;
+ std::ostringstream stdErrForSuite;
+ unsigned int unexpectedExceptions;
+ };
+
+ INTERNAL_CATCH_REGISTER_REPORTER( "junit", JunitReporter )
+
+} // end namespace Catch
+
+// #included from: ../reporters/catch_reporter_console.hpp
+#define TWOBLUECUBES_CATCH_REPORTER_CONSOLE_HPP_INCLUDED
+
+namespace Catch {
+
+ struct ConsoleReporter : StreamingReporterBase {
+ ConsoleReporter( ReporterConfig const& _config )
+ : StreamingReporterBase( _config ),
+ m_headerPrinted( false )
+ {}
+
+ virtual ~ConsoleReporter() CATCH_OVERRIDE;
+ static std::string getDescription() {
+ return "Reports test results as plain lines of text";
+ }
+
+ virtual void noMatchingTestCases( std::string const& spec ) CATCH_OVERRIDE {
+ stream << "No test cases matched '" << spec << "'" << std::endl;
+ }
+
+ virtual void assertionStarting( AssertionInfo const& ) CATCH_OVERRIDE {
+ }
+
+ virtual bool assertionEnded( AssertionStats const& _assertionStats ) CATCH_OVERRIDE {
+ AssertionResult const& result = _assertionStats.assertionResult;
+
+ bool printInfoMessages = true;
+
+ // Drop out if result was successful and we're not printing those
+ if( !m_config->includeSuccessfulResults() && result.isOk() ) {
+ if( result.getResultType() != ResultWas::Warning )
+ return false;
+ printInfoMessages = false;
+ }
+
+ lazyPrint();
+
+ AssertionPrinter printer( stream, _assertionStats, printInfoMessages );
+ printer.print();
+ stream << std::endl;
+ return true;
+ }
+
+ virtual void sectionStarting( SectionInfo const& _sectionInfo ) CATCH_OVERRIDE {
+ m_headerPrinted = false;
+ StreamingReporterBase::sectionStarting( _sectionInfo );
+ }
+ virtual void sectionEnded( SectionStats const& _sectionStats ) CATCH_OVERRIDE {
+ if( _sectionStats.missingAssertions ) {
+ lazyPrint();
+ Colour colour( Colour::ResultError );
+ if( m_sectionStack.size() > 1 )
+ stream << "\nNo assertions in section";
+ else
+ stream << "\nNo assertions in test case";
+ stream << " '" << _sectionStats.sectionInfo.name << "'\n" << std::endl;
+ }
+ if( m_headerPrinted ) {
+ if( m_config->showDurations() == ShowDurations::Always )
+ stream << "Completed in " << _sectionStats.durationInSeconds << "s" << std::endl;
+ m_headerPrinted = false;
+ }
+ else {
+ if( m_config->showDurations() == ShowDurations::Always )
+ stream << _sectionStats.sectionInfo.name << " completed in " << _sectionStats.durationInSeconds << "s" << std::endl;
+ }
+ StreamingReporterBase::sectionEnded( _sectionStats );
+ }
+
+ virtual void testCaseEnded( TestCaseStats const& _testCaseStats ) CATCH_OVERRIDE {
+ StreamingReporterBase::testCaseEnded( _testCaseStats );
+ m_headerPrinted = false;
+ }
+ virtual void testGroupEnded( TestGroupStats const& _testGroupStats ) CATCH_OVERRIDE {
+ if( currentGroupInfo.used ) {
+ printSummaryDivider();
+ stream << "Summary for group '" << _testGroupStats.groupInfo.name << "':\n";
+ printTotals( _testGroupStats.totals );
+ stream << "\n" << std::endl;
+ }
+ StreamingReporterBase::testGroupEnded( _testGroupStats );
+ }
+ virtual void testRunEnded( TestRunStats const& _testRunStats ) CATCH_OVERRIDE {
+ printTotalsDivider( _testRunStats.totals );
+ printTotals( _testRunStats.totals );
+ stream << std::endl;
+ StreamingReporterBase::testRunEnded( _testRunStats );
+ }
+
+ private:
+
+ class AssertionPrinter {
+ void operator= ( AssertionPrinter const& );
+ public:
+ AssertionPrinter( std::ostream& _stream, AssertionStats const& _stats, bool _printInfoMessages )
+ : stream( _stream ),
+ stats( _stats ),
+ result( _stats.assertionResult ),
+ colour( Colour::None ),
+ message( result.getMessage() ),
+ messages( _stats.infoMessages ),
+ printInfoMessages( _printInfoMessages )
+ {
+ switch( result.getResultType() ) {
+ case ResultWas::Ok:
+ colour = Colour::Success;
+ passOrFail = "PASSED";
+ //if( result.hasMessage() )
+ if( _stats.infoMessages.size() == 1 )
+ messageLabel = "with message";
+ if( _stats.infoMessages.size() > 1 )
+ messageLabel = "with messages";
+ break;
+ case ResultWas::ExpressionFailed:
+ if( result.isOk() ) {
+ colour = Colour::Success;
+ passOrFail = "FAILED - but was ok";
+ }
+ else {
+ colour = Colour::Error;
+ passOrFail = "FAILED";
+ }
+ if( _stats.infoMessages.size() == 1 )
+ messageLabel = "with message";
+ if( _stats.infoMessages.size() > 1 )
+ messageLabel = "with messages";
+ break;
+ case ResultWas::ThrewException:
+ colour = Colour::Error;
+ passOrFail = "FAILED";
+ messageLabel = "due to unexpected exception with message";
+ break;
+ case ResultWas::FatalErrorCondition:
+ colour = Colour::Error;
+ passOrFail = "FAILED";
+ messageLabel = "due to a fatal error condition";
+ break;
+ case ResultWas::DidntThrowException:
+ colour = Colour::Error;
+ passOrFail = "FAILED";
+ messageLabel = "because no exception was thrown where one was expected";
+ break;
+ case ResultWas::Info:
+ messageLabel = "info";
+ break;
+ case ResultWas::Warning:
+ messageLabel = "warning";
+ break;
+ case ResultWas::ExplicitFailure:
+ passOrFail = "FAILED";
+ colour = Colour::Error;
+ if( _stats.infoMessages.size() == 1 )
+ messageLabel = "explicitly with message";
+ if( _stats.infoMessages.size() > 1 )
+ messageLabel = "explicitly with messages";
+ break;
+ // These cases are here to prevent compiler warnings
+ case ResultWas::Unknown:
+ case ResultWas::FailureBit:
+ case ResultWas::Exception:
+ passOrFail = "** internal error **";
+ colour = Colour::Error;
+ break;
+ }
+ }
+
+ void print() const {
+ printSourceInfo();
+ if( stats.totals.assertions.total() > 0 ) {
+ if( result.isOk() )
+ stream << "\n";
+ printResultType();
+ printOriginalExpression();
+ printReconstructedExpression();
+ }
+ else {
+ stream << "\n";
+ }
+ printMessage();
+ }
+
+ private:
+ void printResultType() const {
+ if( !passOrFail.empty() ) {
+ Colour colourGuard( colour );
+ stream << passOrFail << ":\n";
+ }
+ }
+ void printOriginalExpression() const {
+ if( result.hasExpression() ) {
+ Colour colourGuard( Colour::OriginalExpression );
+ stream << " ";
+ stream << result.getExpressionInMacro();
+ stream << "\n";
+ }
+ }
+ void printReconstructedExpression() const {
+ if( result.hasExpandedExpression() ) {
+ stream << "with expansion:\n";
+ Colour colourGuard( Colour::ReconstructedExpression );
+ stream << Text( result.getExpandedExpression(), TextAttributes().setIndent(2) ) << "\n";
+ }
+ }
+ void printMessage() const {
+ if( !messageLabel.empty() )
+ stream << messageLabel << ":" << "\n";
+ for( std::vector<MessageInfo>::const_iterator it = messages.begin(), itEnd = messages.end();
+ it != itEnd;
+ ++it ) {
+ // If this assertion is a warning ignore any INFO messages
+ if( printInfoMessages || it->type != ResultWas::Info )
+ stream << Text( it->message, TextAttributes().setIndent(2) ) << "\n";
+ }
+ }
+ void printSourceInfo() const {
+ Colour colourGuard( Colour::FileName );
+ stream << result.getSourceInfo() << ": ";
+ }
+
+ std::ostream& stream;
+ AssertionStats const& stats;
+ AssertionResult const& result;
+ Colour::Code colour;
+ std::string passOrFail;
+ std::string messageLabel;
+ std::string message;
+ std::vector<MessageInfo> messages;
+ bool printInfoMessages;
+ };
+
+ void lazyPrint() {
+
+ if( !currentTestRunInfo.used )
+ lazyPrintRunInfo();
+ if( !currentGroupInfo.used )
+ lazyPrintGroupInfo();
+
+ if( !m_headerPrinted ) {
+ printTestCaseAndSectionHeader();
+ m_headerPrinted = true;
+ }
+ }
+ void lazyPrintRunInfo() {
+ stream << "\n" << getLineOfChars<'~'>() << "\n";
+ Colour colour( Colour::SecondaryText );
+ stream << currentTestRunInfo->name
+ << " is a Catch v" << libraryVersion << " host application.\n"
+ << "Run with -? for options\n\n";
+
+ if( m_config->rngSeed() != 0 )
+ stream << "Randomness seeded to: " << m_config->rngSeed() << "\n\n";
+
+ currentTestRunInfo.used = true;
+ }
+ void lazyPrintGroupInfo() {
+ if( !currentGroupInfo->name.empty() && currentGroupInfo->groupsCounts > 1 ) {
+ printClosedHeader( "Group: " + currentGroupInfo->name );
+ currentGroupInfo.used = true;
+ }
+ }
+ void printTestCaseAndSectionHeader() {
+ assert( !m_sectionStack.empty() );
+ printOpenHeader( currentTestCaseInfo->name );
+
+ if( m_sectionStack.size() > 1 ) {
+ Colour colourGuard( Colour::Headers );
+
+ std::vector<SectionInfo>::const_iterator
+ it = m_sectionStack.begin()+1, // Skip first section (test case)
+ itEnd = m_sectionStack.end();
+ for( ; it != itEnd; ++it )
+ printHeaderString( it->name, 2 );
+ }
+
+ SourceLineInfo lineInfo = m_sectionStack.front().lineInfo;
+
+ if( !lineInfo.empty() ){
+ stream << getLineOfChars<'-'>() << "\n";
+ Colour colourGuard( Colour::FileName );
+ stream << lineInfo << "\n";
+ }
+ stream << getLineOfChars<'.'>() << "\n" << std::endl;
+ }
+
+ void printClosedHeader( std::string const& _name ) {
+ printOpenHeader( _name );
+ stream << getLineOfChars<'.'>() << "\n";
+ }
+ void printOpenHeader( std::string const& _name ) {
+ stream << getLineOfChars<'-'>() << "\n";
+ {
+ Colour colourGuard( Colour::Headers );
+ printHeaderString( _name );
+ }
+ }
+
+ // if string has a : in first line will set indent to follow it on
+ // subsequent lines
+ void printHeaderString( std::string const& _string, std::size_t indent = 0 ) {
+ std::size_t i = _string.find( ": " );
+ if( i != std::string::npos )
+ i+=2;
+ else
+ i = 0;
+ stream << Text( _string, TextAttributes()
+ .setIndent( indent+i)
+ .setInitialIndent( indent ) ) << "\n";
+ }
+
+ struct SummaryColumn {
+
+ SummaryColumn( std::string const& _label, Colour::Code _colour )
+ : label( _label ),
+ colour( _colour )
+ {}
+ SummaryColumn addRow( std::size_t count ) {
+ std::ostringstream oss;
+ oss << count;
+ std::string row = oss.str();
+ for( std::vector<std::string>::iterator it = rows.begin(); it != rows.end(); ++it ) {
+ while( it->size() < row.size() )
+ *it = " " + *it;
+ while( it->size() > row.size() )
+ row = " " + row;
+ }
+ rows.push_back( row );
+ return *this;
+ }
+
+ std::string label;
+ Colour::Code colour;
+ std::vector<std::string> rows;
+
+ };
+
+ void printTotals( Totals const& totals ) {
+ if( totals.testCases.total() == 0 ) {
+ stream << Colour( Colour::Warning ) << "No tests ran\n";
+ }
+ else if( totals.assertions.total() > 0 && totals.testCases.allPassed() ) {
+ stream << Colour( Colour::ResultSuccess ) << "All tests passed";
+ stream << " ("
+ << pluralise( totals.assertions.passed, "assertion" ) << " in "
+ << pluralise( totals.testCases.passed, "test case" ) << ")"
+ << "\n";
+ }
+ else {
+
+ std::vector<SummaryColumn> columns;
+ columns.push_back( SummaryColumn( "", Colour::None )
+ .addRow( totals.testCases.total() )
+ .addRow( totals.assertions.total() ) );
+ columns.push_back( SummaryColumn( "passed", Colour::Success )
+ .addRow( totals.testCases.passed )
+ .addRow( totals.assertions.passed ) );
+ columns.push_back( SummaryColumn( "failed", Colour::ResultError )
+ .addRow( totals.testCases.failed )
+ .addRow( totals.assertions.failed ) );
+ columns.push_back( SummaryColumn( "failed as expected", Colour::ResultExpectedFailure )
+ .addRow( totals.testCases.failedButOk )
+ .addRow( totals.assertions.failedButOk ) );
+
+ printSummaryRow( "test cases", columns, 0 );
+ printSummaryRow( "assertions", columns, 1 );
+ }
+ }
+ void printSummaryRow( std::string const& label, std::vector<SummaryColumn> const& cols, std::size_t row ) {
+ for( std::vector<SummaryColumn>::const_iterator it = cols.begin(); it != cols.end(); ++it ) {
+ std::string value = it->rows[row];
+ if( it->label.empty() ) {
+ stream << label << ": ";
+ if( value != "0" )
+ stream << value;
+ else
+ stream << Colour( Colour::Warning ) << "- none -";
+ }
+ else if( value != "0" ) {
+ stream << Colour( Colour::LightGrey ) << " | ";
+ stream << Colour( it->colour )
+ << value << " " << it->label;
+ }
+ }
+ stream << "\n";
+ }
+
+ static std::size_t makeRatio( std::size_t number, std::size_t total ) {
+ std::size_t ratio = total > 0 ? CATCH_CONFIG_CONSOLE_WIDTH * number/ total : 0;
+ return ( ratio == 0 && number > 0 ) ? 1 : ratio;
+ }
+ static std::size_t& findMax( std::size_t& i, std::size_t& j, std::size_t& k ) {
+ if( i > j && i > k )
+ return i;
+ else if( j > k )
+ return j;
+ else
+ return k;
+ }
+
+ void printTotalsDivider( Totals const& totals ) {
+ if( totals.testCases.total() > 0 ) {
+ std::size_t failedRatio = makeRatio( totals.testCases.failed, totals.testCases.total() );
+ std::size_t failedButOkRatio = makeRatio( totals.testCases.failedButOk, totals.testCases.total() );
+ std::size_t passedRatio = makeRatio( totals.testCases.passed, totals.testCases.total() );
+ while( failedRatio + failedButOkRatio + passedRatio < CATCH_CONFIG_CONSOLE_WIDTH-1 )
+ findMax( failedRatio, failedButOkRatio, passedRatio )++;
+ while( failedRatio + failedButOkRatio + passedRatio > CATCH_CONFIG_CONSOLE_WIDTH-1 )
+ findMax( failedRatio, failedButOkRatio, passedRatio )--;
+
+ stream << Colour( Colour::Error ) << std::string( failedRatio, '=' );
+ stream << Colour( Colour::ResultExpectedFailure ) << std::string( failedButOkRatio, '=' );
+ if( totals.testCases.allPassed() )
+ stream << Colour( Colour::ResultSuccess ) << std::string( passedRatio, '=' );
+ else
+ stream << Colour( Colour::Success ) << std::string( passedRatio, '=' );
+ }
+ else {
+ stream << Colour( Colour::Warning ) << std::string( CATCH_CONFIG_CONSOLE_WIDTH-1, '=' );
+ }
+ stream << "\n";
+ }
+ void printSummaryDivider() {
+ stream << getLineOfChars<'-'>() << "\n";
+ }
+
+ private:
+ bool m_headerPrinted;
+ };
+
+ INTERNAL_CATCH_REGISTER_REPORTER( "console", ConsoleReporter )
+
+} // end namespace Catch
+
+// #included from: ../reporters/catch_reporter_compact.hpp
+#define TWOBLUECUBES_CATCH_REPORTER_COMPACT_HPP_INCLUDED
+
+namespace Catch {
+
+ struct CompactReporter : StreamingReporterBase {
+
+ CompactReporter( ReporterConfig const& _config )
+ : StreamingReporterBase( _config )
+ {}
+
+ virtual ~CompactReporter();
+
+ static std::string getDescription() {
+ return "Reports test results on a single line, suitable for IDEs";
+ }
+
+ virtual ReporterPreferences getPreferences() const {
+ ReporterPreferences prefs;
+ prefs.shouldRedirectStdOut = false;
+ return prefs;
+ }
+
+ virtual void noMatchingTestCases( std::string const& spec ) {
+ stream << "No test cases matched '" << spec << "'" << std::endl;
+ }
+
+ virtual void assertionStarting( AssertionInfo const& ) {
+ }
+
+ virtual bool assertionEnded( AssertionStats const& _assertionStats ) {
+ AssertionResult const& result = _assertionStats.assertionResult;
+
+ bool printInfoMessages = true;
+
+ // Drop out if result was successful and we're not printing those
+ if( !m_config->includeSuccessfulResults() && result.isOk() ) {
+ if( result.getResultType() != ResultWas::Warning )
+ return false;
+ printInfoMessages = false;
+ }
+
+ AssertionPrinter printer( stream, _assertionStats, printInfoMessages );
+ printer.print();
+
+ stream << std::endl;
+ return true;
+ }
+
+ virtual void testRunEnded( TestRunStats const& _testRunStats ) {
+ printTotals( _testRunStats.totals );
+ stream << "\n" << std::endl;
+ StreamingReporterBase::testRunEnded( _testRunStats );
+ }
+
+ private:
+ class AssertionPrinter {
+ void operator= ( AssertionPrinter const& );
+ public:
+ AssertionPrinter( std::ostream& _stream, AssertionStats const& _stats, bool _printInfoMessages )
+ : stream( _stream )
+ , stats( _stats )
+ , result( _stats.assertionResult )
+ , messages( _stats.infoMessages )
+ , itMessage( _stats.infoMessages.begin() )
+ , printInfoMessages( _printInfoMessages )
+ {}
+
+ void print() {
+ printSourceInfo();
+
+ itMessage = messages.begin();
+
+ switch( result.getResultType() ) {
+ case ResultWas::Ok:
+ printResultType( Colour::ResultSuccess, passedString() );
+ printOriginalExpression();
+ printReconstructedExpression();
+ if ( ! result.hasExpression() )
+ printRemainingMessages( Colour::None );
+ else
+ printRemainingMessages();
+ break;
+ case ResultWas::ExpressionFailed:
+ if( result.isOk() )
+ printResultType( Colour::ResultSuccess, failedString() + std::string( " - but was ok" ) );
+ else
+ printResultType( Colour::Error, failedString() );
+ printOriginalExpression();
+ printReconstructedExpression();
+ printRemainingMessages();
+ break;
+ case ResultWas::ThrewException:
+ printResultType( Colour::Error, failedString() );
+ printIssue( "unexpected exception with message:" );
+ printMessage();
+ printExpressionWas();
+ printRemainingMessages();
+ break;
+ case ResultWas::FatalErrorCondition:
+ printResultType( Colour::Error, failedString() );
+ printIssue( "fatal error condition with message:" );
+ printMessage();
+ printExpressionWas();
+ printRemainingMessages();
+ break;
+ case ResultWas::DidntThrowException:
+ printResultType( Colour::Error, failedString() );
+ printIssue( "expected exception, got none" );
+ printExpressionWas();
+ printRemainingMessages();
+ break;
+ case ResultWas::Info:
+ printResultType( Colour::None, "info" );
+ printMessage();
+ printRemainingMessages();
+ break;
+ case ResultWas::Warning:
+ printResultType( Colour::None, "warning" );
+ printMessage();
+ printRemainingMessages();
+ break;
+ case ResultWas::ExplicitFailure:
+ printResultType( Colour::Error, failedString() );
+ printIssue( "explicitly" );
+ printRemainingMessages( Colour::None );
+ break;
+ // These cases are here to prevent compiler warnings
+ case ResultWas::Unknown:
+ case ResultWas::FailureBit:
+ case ResultWas::Exception:
+ printResultType( Colour::Error, "** internal error **" );
+ break;
+ }
+ }
+
+ private:
+ // Colour::LightGrey
+
+ static Colour::Code dimColour() { return Colour::FileName; }
+
+#ifdef CATCH_PLATFORM_MAC
+ static const char* failedString() { return "FAILED"; }
+ static const char* passedString() { return "PASSED"; }
+#else
+ static const char* failedString() { return "failed"; }
+ static const char* passedString() { return "passed"; }
+#endif
+
+ void printSourceInfo() const {
+ Colour colourGuard( Colour::FileName );
+ stream << result.getSourceInfo() << ":";
+ }
+
+ void printResultType( Colour::Code colour, std::string passOrFail ) const {
+ if( !passOrFail.empty() ) {
+ {
+ Colour colourGuard( colour );
+ stream << " " << passOrFail;
+ }
+ stream << ":";
+ }
+ }
+
+ void printIssue( std::string issue ) const {
+ stream << " " << issue;
+ }
+
+ void printExpressionWas() {
+ if( result.hasExpression() ) {
+ stream << ";";
+ {
+ Colour colour( dimColour() );
+ stream << " expression was:";
+ }
+ printOriginalExpression();
+ }
+ }
+
+ void printOriginalExpression() const {
+ if( result.hasExpression() ) {
+ stream << " " << result.getExpression();
+ }
+ }
+
+ void printReconstructedExpression() const {
+ if( result.hasExpandedExpression() ) {
+ {
+ Colour colour( dimColour() );
+ stream << " for: ";
+ }
+ stream << result.getExpandedExpression();
+ }
+ }
+
+ void printMessage() {
+ if ( itMessage != messages.end() ) {
+ stream << " '" << itMessage->message << "'";
+ ++itMessage;
+ }
+ }
+
+ void printRemainingMessages( Colour::Code colour = dimColour() ) {
+ if ( itMessage == messages.end() )
+ return;
+
+ // using messages.end() directly yields compilation error:
+ std::vector<MessageInfo>::const_iterator itEnd = messages.end();
+ const std::size_t N = static_cast<std::size_t>( std::distance( itMessage, itEnd ) );
+
+ {
+ Colour colourGuard( colour );
+ stream << " with " << pluralise( N, "message" ) << ":";
+ }
+
+ for(; itMessage != itEnd; ) {
+ // If this assertion is a warning ignore any INFO messages
+ if( printInfoMessages || itMessage->type != ResultWas::Info ) {
+ stream << " '" << itMessage->message << "'";
+ if ( ++itMessage != itEnd ) {
+ Colour colourGuard( dimColour() );
+ stream << " and";
+ }
+ }
+ }
+ }
+
+ private:
+ std::ostream& stream;
+ AssertionStats const& stats;
+ AssertionResult const& result;
+ std::vector<MessageInfo> messages;
+ std::vector<MessageInfo>::const_iterator itMessage;
+ bool printInfoMessages;
+ };
+
+ // Colour, message variants:
+ // - white: No tests ran.
+ // - red: Failed [both/all] N test cases, failed [both/all] M assertions.
+ // - white: Passed [both/all] N test cases (no assertions).
+ // - red: Failed N tests cases, failed M assertions.
+ // - green: Passed [both/all] N tests cases with M assertions.
+
+ std::string bothOrAll( std::size_t count ) const {
+ return count == 1 ? "" : count == 2 ? "both " : "all " ;
+ }
+
+ void printTotals( const Totals& totals ) const {
+ if( totals.testCases.total() == 0 ) {
+ stream << "No tests ran.";
+ }
+ else if( totals.testCases.failed == totals.testCases.total() ) {
+ Colour colour( Colour::ResultError );
+ const std::string qualify_assertions_failed =
+ totals.assertions.failed == totals.assertions.total() ?
+ bothOrAll( totals.assertions.failed ) : "";
+ stream <<
+ "Failed " << bothOrAll( totals.testCases.failed )
+ << pluralise( totals.testCases.failed, "test case" ) << ", "
+ "failed " << qualify_assertions_failed <<
+ pluralise( totals.assertions.failed, "assertion" ) << ".";
+ }
+ else if( totals.assertions.total() == 0 ) {
+ stream <<
+ "Passed " << bothOrAll( totals.testCases.total() )
+ << pluralise( totals.testCases.total(), "test case" )
+ << " (no assertions).";
+ }
+ else if( totals.assertions.failed ) {
+ Colour colour( Colour::ResultError );
+ stream <<
+ "Failed " << pluralise( totals.testCases.failed, "test case" ) << ", "
+ "failed " << pluralise( totals.assertions.failed, "assertion" ) << ".";
+ }
+ else {
+ Colour colour( Colour::ResultSuccess );
+ stream <<
+ "Passed " << bothOrAll( totals.testCases.passed )
+ << pluralise( totals.testCases.passed, "test case" ) <<
+ " with " << pluralise( totals.assertions.passed, "assertion" ) << ".";
+ }
+ }
+ };
+
+ INTERNAL_CATCH_REGISTER_REPORTER( "compact", CompactReporter )
+
+} // end namespace Catch
+
+namespace Catch {
+ // These are all here to avoid warnings about not having any out of line
+ // virtual methods
+ NonCopyable::~NonCopyable() {}
+ IShared::~IShared() {}
+ IStream::~IStream() CATCH_NOEXCEPT {}
+ FileStream::~FileStream() CATCH_NOEXCEPT {}
+ CoutStream::~CoutStream() CATCH_NOEXCEPT {}
+ DebugOutStream::~DebugOutStream() CATCH_NOEXCEPT {}
+ StreamBufBase::~StreamBufBase() CATCH_NOEXCEPT {}
+ IContext::~IContext() {}
+ IResultCapture::~IResultCapture() {}
+ ITestCase::~ITestCase() {}
+ ITestCaseRegistry::~ITestCaseRegistry() {}
+ IRegistryHub::~IRegistryHub() {}
+ IMutableRegistryHub::~IMutableRegistryHub() {}
+ IExceptionTranslator::~IExceptionTranslator() {}
+ IExceptionTranslatorRegistry::~IExceptionTranslatorRegistry() {}
+ IReporter::~IReporter() {}
+ IReporterFactory::~IReporterFactory() {}
+ IReporterRegistry::~IReporterRegistry() {}
+ IStreamingReporter::~IStreamingReporter() {}
+ AssertionStats::~AssertionStats() {}
+ SectionStats::~SectionStats() {}
+ TestCaseStats::~TestCaseStats() {}
+ TestGroupStats::~TestGroupStats() {}
+ TestRunStats::~TestRunStats() {}
+ CumulativeReporterBase::SectionNode::~SectionNode() {}
+ CumulativeReporterBase::~CumulativeReporterBase() {}
+
+ StreamingReporterBase::~StreamingReporterBase() {}
+ ConsoleReporter::~ConsoleReporter() {}
+ CompactReporter::~CompactReporter() {}
+ IRunner::~IRunner() {}
+ IMutableContext::~IMutableContext() {}
+ IConfig::~IConfig() {}
+ XmlReporter::~XmlReporter() {}
+ JunitReporter::~JunitReporter() {}
+ TestRegistry::~TestRegistry() {}
+ FreeFunctionTestCase::~FreeFunctionTestCase() {}
+ IGeneratorInfo::~IGeneratorInfo() {}
+ IGeneratorsForTest::~IGeneratorsForTest() {}
+ WildcardPattern::~WildcardPattern() {}
+ TestSpec::Pattern::~Pattern() {}
+ TestSpec::NamePattern::~NamePattern() {}
+ TestSpec::TagPattern::~TagPattern() {}
+ TestSpec::ExcludedPattern::~ExcludedPattern() {}
+
+ Matchers::Impl::StdString::Equals::~Equals() {}
+ Matchers::Impl::StdString::Contains::~Contains() {}
+ Matchers::Impl::StdString::StartsWith::~StartsWith() {}
+ Matchers::Impl::StdString::EndsWith::~EndsWith() {}
+
+ void Config::dummy() {}
+
+ namespace TestCaseTracking {
+ ITracker::~ITracker() {}
+ TrackerBase::~TrackerBase() {}
+ SectionTracker::~SectionTracker() {}
+ IndexTracker::~IndexTracker() {}
+ }
+}
+
+#ifdef __clang__
+#pragma clang diagnostic pop
+#endif
+
+#endif
+
+#ifdef CATCH_CONFIG_MAIN
+// #included from: internal/catch_default_main.hpp
+#define TWOBLUECUBES_CATCH_DEFAULT_MAIN_HPP_INCLUDED
+
+#ifndef __OBJC__
+
+// Standard C/C++ main entry point
+int main (int argc, char * argv[]) {
+ return Catch::Session().run( argc, argv );
+}
+
+#else // __OBJC__
+
+// Objective-C entry point
+int main (int argc, char * const argv[]) {
+#if !CATCH_ARC_ENABLED
+ NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
+#endif
+
+ Catch::registerTestMethods();
+ int result = Catch::Session().run( argc, (char* const*)argv );
+
+#if !CATCH_ARC_ENABLED
+ [pool drain];
+#endif
+
+ return result;
+}
+
+#endif // __OBJC__
+
+#endif
+
+#ifdef CLARA_CONFIG_MAIN_NOT_DEFINED
+# undef CLARA_CONFIG_MAIN
+#endif
+
+//////
+
+// If this config identifier is defined then all CATCH macros are prefixed with CATCH_
+#ifdef CATCH_CONFIG_PREFIX_ALL
+
+#define CATCH_REQUIRE( expr ) INTERNAL_CATCH_TEST( expr, Catch::ResultDisposition::Normal, "CATCH_REQUIRE" )
+#define CATCH_REQUIRE_FALSE( expr ) INTERNAL_CATCH_TEST( expr, Catch::ResultDisposition::Normal | Catch::ResultDisposition::FalseTest, "CATCH_REQUIRE_FALSE" )
+
+#define CATCH_REQUIRE_THROWS( expr ) INTERNAL_CATCH_THROWS( expr, Catch::ResultDisposition::Normal, "", "CATCH_REQUIRE_THROWS" )
+#define CATCH_REQUIRE_THROWS_AS( expr, exceptionType ) INTERNAL_CATCH_THROWS_AS( expr, exceptionType, Catch::ResultDisposition::Normal, "CATCH_REQUIRE_THROWS_AS" )
+#define CATCH_REQUIRE_THROWS_WITH( expr, matcher ) INTERNAL_CATCH_THROWS( expr, Catch::ResultDisposition::Normal, matcher, "CATCH_REQUIRE_THROWS_WITH" )
+#define CATCH_REQUIRE_NOTHROW( expr ) INTERNAL_CATCH_NO_THROW( expr, Catch::ResultDisposition::Normal, "CATCH_REQUIRE_NOTHROW" )
+
+#define CATCH_CHECK( expr ) INTERNAL_CATCH_TEST( expr, Catch::ResultDisposition::ContinueOnFailure, "CATCH_CHECK" )
+#define CATCH_CHECK_FALSE( expr ) INTERNAL_CATCH_TEST( expr, Catch::ResultDisposition::ContinueOnFailure | Catch::ResultDisposition::FalseTest, "CATCH_CHECK_FALSE" )
+#define CATCH_CHECKED_IF( expr ) INTERNAL_CATCH_IF( expr, Catch::ResultDisposition::ContinueOnFailure, "CATCH_CHECKED_IF" )
+#define CATCH_CHECKED_ELSE( expr ) INTERNAL_CATCH_ELSE( expr, Catch::ResultDisposition::ContinueOnFailure, "CATCH_CHECKED_ELSE" )
+#define CATCH_CHECK_NOFAIL( expr ) INTERNAL_CATCH_TEST( expr, Catch::ResultDisposition::ContinueOnFailure | Catch::ResultDisposition::SuppressFail, "CATCH_CHECK_NOFAIL" )
+
+#define CATCH_CHECK_THROWS( expr ) INTERNAL_CATCH_THROWS( expr, Catch::ResultDisposition::ContinueOnFailure, "CATCH_CHECK_THROWS" )
+#define CATCH_CHECK_THROWS_AS( expr, exceptionType ) INTERNAL_CATCH_THROWS_AS( expr, exceptionType, Catch::ResultDisposition::ContinueOnFailure, "CATCH_CHECK_THROWS_AS" )
+#define CATCH_CHECK_THROWS_WITH( expr, matcher ) INTERNAL_CATCH_THROWS( expr, Catch::ResultDisposition::ContinueOnFailure, matcher, "CATCH_CHECK_THROWS_WITH" )
+#define CATCH_CHECK_NOTHROW( expr ) INTERNAL_CATCH_NO_THROW( expr, Catch::ResultDisposition::ContinueOnFailure, "CATCH_CHECK_NOTHROW" )
+
+#define CHECK_THAT( arg, matcher ) INTERNAL_CHECK_THAT( arg, matcher, Catch::ResultDisposition::ContinueOnFailure, "CATCH_CHECK_THAT" )
+#define CATCH_REQUIRE_THAT( arg, matcher ) INTERNAL_CHECK_THAT( arg, matcher, Catch::ResultDisposition::Normal, "CATCH_REQUIRE_THAT" )
+
+#define CATCH_INFO( msg ) INTERNAL_CATCH_INFO( msg, "CATCH_INFO" )
+#define CATCH_WARN( msg ) INTERNAL_CATCH_MSG( Catch::ResultWas::Warning, Catch::ResultDisposition::ContinueOnFailure, "CATCH_WARN", msg )
+#define CATCH_SCOPED_INFO( msg ) INTERNAL_CATCH_INFO( msg, "CATCH_INFO" )
+#define CATCH_CAPTURE( msg ) INTERNAL_CATCH_INFO( #msg " := " << msg, "CATCH_CAPTURE" )
+#define CATCH_SCOPED_CAPTURE( msg ) INTERNAL_CATCH_INFO( #msg " := " << msg, "CATCH_CAPTURE" )
+
+#ifdef CATCH_CONFIG_VARIADIC_MACROS
+ #define CATCH_TEST_CASE( ... ) INTERNAL_CATCH_TESTCASE( __VA_ARGS__ )
+ #define CATCH_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TEST_CASE_METHOD( className, __VA_ARGS__ )
+ #define CATCH_METHOD_AS_TEST_CASE( method, ... ) INTERNAL_CATCH_METHOD_AS_TEST_CASE( method, __VA_ARGS__ )
+ #define CATCH_REGISTER_TEST_CASE( Function, ... ) INTERNAL_CATCH_REGISTER_TESTCASE( Function, __VA_ARGS__ )
+ #define CATCH_SECTION( ... ) INTERNAL_CATCH_SECTION( __VA_ARGS__ )
+ #define CATCH_FAIL( ... ) INTERNAL_CATCH_MSG( Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::Normal, "CATCH_FAIL", __VA_ARGS__ )
+ #define CATCH_SUCCEED( ... ) INTERNAL_CATCH_MSG( Catch::ResultWas::Ok, Catch::ResultDisposition::ContinueOnFailure, "CATCH_SUCCEED", __VA_ARGS__ )
+#else
+ #define CATCH_TEST_CASE( name, description ) INTERNAL_CATCH_TESTCASE( name, description )
+ #define CATCH_TEST_CASE_METHOD( className, name, description ) INTERNAL_CATCH_TEST_CASE_METHOD( className, name, description )
+ #define CATCH_METHOD_AS_TEST_CASE( method, name, description ) INTERNAL_CATCH_METHOD_AS_TEST_CASE( method, name, description )
+ #define CATCH_REGISTER_TEST_CASE( function, name, description ) INTERNAL_CATCH_REGISTER_TESTCASE( function, name, description )
+ #define CATCH_SECTION( name, description ) INTERNAL_CATCH_SECTION( name, description )
+ #define CATCH_FAIL( msg ) INTERNAL_CATCH_MSG( Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::Normal, "CATCH_FAIL", msg )
+ #define CATCH_SUCCEED( msg ) INTERNAL_CATCH_MSG( Catch::ResultWas::Ok, Catch::ResultDisposition::ContinueOnFailure, "CATCH_SUCCEED", msg )
+#endif
+#define CATCH_ANON_TEST_CASE() INTERNAL_CATCH_TESTCASE( "", "" )
+
+#define CATCH_REGISTER_REPORTER( name, reporterType ) INTERNAL_CATCH_REGISTER_REPORTER( name, reporterType )
+#define CATCH_REGISTER_LEGACY_REPORTER( name, reporterType ) INTERNAL_CATCH_REGISTER_LEGACY_REPORTER( name, reporterType )
+
+#define CATCH_GENERATE( expr) INTERNAL_CATCH_GENERATE( expr )
+
+// "BDD-style" convenience wrappers
+#ifdef CATCH_CONFIG_VARIADIC_MACROS
+#define CATCH_SCENARIO( ... ) CATCH_TEST_CASE( "Scenario: " __VA_ARGS__ )
+#define CATCH_SCENARIO_METHOD( className, ... ) INTERNAL_CATCH_TEST_CASE_METHOD( className, "Scenario: " __VA_ARGS__ )
+#else
+#define CATCH_SCENARIO( name, tags ) CATCH_TEST_CASE( "Scenario: " name, tags )
+#define CATCH_SCENARIO_METHOD( className, name, tags ) INTERNAL_CATCH_TEST_CASE_METHOD( className, "Scenario: " name, tags )
+#endif
+#define CATCH_GIVEN( desc ) CATCH_SECTION( std::string( "Given: ") + desc, "" )
+#define CATCH_WHEN( desc ) CATCH_SECTION( std::string( " When: ") + desc, "" )
+#define CATCH_AND_WHEN( desc ) CATCH_SECTION( std::string( " And: ") + desc, "" )
+#define CATCH_THEN( desc ) CATCH_SECTION( std::string( " Then: ") + desc, "" )
+#define CATCH_AND_THEN( desc ) CATCH_SECTION( std::string( " And: ") + desc, "" )
+
+// If CATCH_CONFIG_PREFIX_ALL is not defined then the CATCH_ prefix is not required
+#else
+
+#define REQUIRE( expr ) INTERNAL_CATCH_TEST( expr, Catch::ResultDisposition::Normal, "REQUIRE" )
+#define REQUIRE_FALSE( expr ) INTERNAL_CATCH_TEST( expr, Catch::ResultDisposition::Normal | Catch::ResultDisposition::FalseTest, "REQUIRE_FALSE" )
+
+#define REQUIRE_THROWS( expr ) INTERNAL_CATCH_THROWS( expr, Catch::ResultDisposition::Normal, "", "REQUIRE_THROWS" )
+#define REQUIRE_THROWS_AS( expr, exceptionType ) INTERNAL_CATCH_THROWS_AS( expr, exceptionType, Catch::ResultDisposition::Normal, "REQUIRE_THROWS_AS" )
+#define REQUIRE_THROWS_WITH( expr, matcher ) INTERNAL_CATCH_THROWS( expr, Catch::ResultDisposition::Normal, matcher, "REQUIRE_THROWS_WITH" )
+#define REQUIRE_NOTHROW( expr ) INTERNAL_CATCH_NO_THROW( expr, Catch::ResultDisposition::Normal, "REQUIRE_NOTHROW" )
+
+#define CHECK( expr ) INTERNAL_CATCH_TEST( expr, Catch::ResultDisposition::ContinueOnFailure, "CHECK" )
+#define CHECK_FALSE( expr ) INTERNAL_CATCH_TEST( expr, Catch::ResultDisposition::ContinueOnFailure | Catch::ResultDisposition::FalseTest, "CHECK_FALSE" )
+#define CHECKED_IF( expr ) INTERNAL_CATCH_IF( expr, Catch::ResultDisposition::ContinueOnFailure, "CHECKED_IF" )
+#define CHECKED_ELSE( expr ) INTERNAL_CATCH_ELSE( expr, Catch::ResultDisposition::ContinueOnFailure, "CHECKED_ELSE" )
+#define CHECK_NOFAIL( expr ) INTERNAL_CATCH_TEST( expr, Catch::ResultDisposition::ContinueOnFailure | Catch::ResultDisposition::SuppressFail, "CHECK_NOFAIL" )
+
+#define CHECK_THROWS( expr ) INTERNAL_CATCH_THROWS( expr, Catch::ResultDisposition::ContinueOnFailure, "", "CHECK_THROWS" )
+#define CHECK_THROWS_AS( expr, exceptionType ) INTERNAL_CATCH_THROWS_AS( expr, exceptionType, Catch::ResultDisposition::ContinueOnFailure, "CHECK_THROWS_AS" )
+#define CHECK_THROWS_WITH( expr, matcher ) INTERNAL_CATCH_THROWS( expr, Catch::ResultDisposition::ContinueOnFailure, matcher, "CHECK_THROWS_WITH" )
+#define CHECK_NOTHROW( expr ) INTERNAL_CATCH_NO_THROW( expr, Catch::ResultDisposition::ContinueOnFailure, "CHECK_NOTHROW" )
+
+#define CHECK_THAT( arg, matcher ) INTERNAL_CHECK_THAT( arg, matcher, Catch::ResultDisposition::ContinueOnFailure, "CHECK_THAT" )
+#define REQUIRE_THAT( arg, matcher ) INTERNAL_CHECK_THAT( arg, matcher, Catch::ResultDisposition::Normal, "REQUIRE_THAT" )
+
+#define INFO( msg ) INTERNAL_CATCH_INFO( msg, "INFO" )
+#define WARN( msg ) INTERNAL_CATCH_MSG( Catch::ResultWas::Warning, Catch::ResultDisposition::ContinueOnFailure, "WARN", msg )
+#define SCOPED_INFO( msg ) INTERNAL_CATCH_INFO( msg, "INFO" )
+#define CAPTURE( msg ) INTERNAL_CATCH_INFO( #msg " := " << msg, "CAPTURE" )
+#define SCOPED_CAPTURE( msg ) INTERNAL_CATCH_INFO( #msg " := " << msg, "CAPTURE" )
+
+#ifdef CATCH_CONFIG_VARIADIC_MACROS
+ #define TEST_CASE( ... ) INTERNAL_CATCH_TESTCASE( __VA_ARGS__ )
+ #define TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TEST_CASE_METHOD( className, __VA_ARGS__ )
+ #define METHOD_AS_TEST_CASE( method, ... ) INTERNAL_CATCH_METHOD_AS_TEST_CASE( method, __VA_ARGS__ )
+ #define REGISTER_TEST_CASE( Function, ... ) INTERNAL_CATCH_REGISTER_TESTCASE( Function, __VA_ARGS__ )
+ #define SECTION( ... ) INTERNAL_CATCH_SECTION( __VA_ARGS__ )
+ #define FAIL( ... ) INTERNAL_CATCH_MSG( Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::Normal, "FAIL", __VA_ARGS__ )
+ #define SUCCEED( ... ) INTERNAL_CATCH_MSG( Catch::ResultWas::Ok, Catch::ResultDisposition::ContinueOnFailure, "SUCCEED", __VA_ARGS__ )
+#else
+ #define TEST_CASE( name, description ) INTERNAL_CATCH_TESTCASE( name, description )
+ #define TEST_CASE_METHOD( className, name, description ) INTERNAL_CATCH_TEST_CASE_METHOD( className, name, description )
+ #define METHOD_AS_TEST_CASE( method, name, description ) INTERNAL_CATCH_METHOD_AS_TEST_CASE( method, name, description )
+ #define REGISTER_TEST_CASE( method, name, description ) INTERNAL_CATCH_REGISTER_TESTCASE( method, name, description )
+ #define SECTION( name, description ) INTERNAL_CATCH_SECTION( name, description )
+ #define FAIL( msg ) INTERNAL_CATCH_MSG( Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::Normal, "FAIL", msg )
+ #define SUCCEED( msg ) INTERNAL_CATCH_MSG( Catch::ResultWas::Ok, Catch::ResultDisposition::ContinueOnFailure, "SUCCEED", msg )
+#endif
+#define ANON_TEST_CASE() INTERNAL_CATCH_TESTCASE( "", "" )
+
+#define REGISTER_REPORTER( name, reporterType ) INTERNAL_CATCH_REGISTER_REPORTER( name, reporterType )
+#define REGISTER_LEGACY_REPORTER( name, reporterType ) INTERNAL_CATCH_REGISTER_LEGACY_REPORTER( name, reporterType )
+
+#define GENERATE( expr) INTERNAL_CATCH_GENERATE( expr )
+
+#endif
+
+#define CATCH_TRANSLATE_EXCEPTION( signature ) INTERNAL_CATCH_TRANSLATE_EXCEPTION( signature )
+
+// "BDD-style" convenience wrappers
+#ifdef CATCH_CONFIG_VARIADIC_MACROS
+#define SCENARIO( ... ) TEST_CASE( "Scenario: " __VA_ARGS__ )
+#define SCENARIO_METHOD( className, ... ) INTERNAL_CATCH_TEST_CASE_METHOD( className, "Scenario: " __VA_ARGS__ )
+#else
+#define SCENARIO( name, tags ) TEST_CASE( "Scenario: " name, tags )
+#define SCENARIO_METHOD( className, name, tags ) INTERNAL_CATCH_TEST_CASE_METHOD( className, "Scenario: " name, tags )
+#endif
+#define GIVEN( desc ) SECTION( std::string(" Given: ") + desc, "" )
+#define WHEN( desc ) SECTION( std::string(" When: ") + desc, "" )
+#define AND_WHEN( desc ) SECTION( std::string("And when: ") + desc, "" )
+#define THEN( desc ) SECTION( std::string(" Then: ") + desc, "" )
+#define AND_THEN( desc ) SECTION( std::string(" And: ") + desc, "" )
+
+using Catch::Detail::Approx;
+
+#endif // TWOBLUECUBES_SINGLE_INCLUDE_CATCH_HPP_INCLUDED
+
diff --git a/3rdparty/bx/makefile b/3rdparty/bx/makefile
index 5d0ecbd8b7d..3093021a698 100644
--- a/3rdparty/bx/makefile
+++ b/3rdparty/bx/makefile
@@ -174,6 +174,7 @@ docs:
clean:
@echo Cleaning...
-@rm -rf .build
+ @mkdir .build
###
diff --git a/3rdparty/bx/scripts/genie.lua b/3rdparty/bx/scripts/genie.lua
index 580e3d66157..fdde771d60d 100644
--- a/3rdparty/bx/scripts/genie.lua
+++ b/3rdparty/bx/scripts/genie.lua
@@ -32,7 +32,6 @@ function copyLib()
end
dofile "bx.lua"
-dofile "unittest++.lua"
dofile "bin2c.lua"
project "bx.test"
@@ -46,11 +45,7 @@ project "bx.test"
includedirs {
path.join(BX_DIR, "include"),
- path.join(BX_THIRD_PARTY_DIR, "UnitTest++/src"),
- }
-
- links {
- "UnitTest++",
+ BX_THIRD_PARTY_DIR,
}
files {
diff --git a/3rdparty/bx/scripts/toolchain.lua b/3rdparty/bx/scripts/toolchain.lua
index d7d1ec8f189..a77b5f71ebd 100644
--- a/3rdparty/bx/scripts/toolchain.lua
+++ b/3rdparty/bx/scripts/toolchain.lua
@@ -100,7 +100,9 @@ function toolchain(_buildDir, _libDir)
location (path.join(_buildDir, "projects", _ACTION))
if _ACTION == "clean" then
- os.rmdir(BUILD_DIR)
+ os.rmdir(_buildDir)
+ os.mkdir(_buildDir)
+ os.exit(1)
end
local androidPlatform = "android-14"
@@ -288,7 +290,7 @@ function toolchain(_buildDir, _libDir)
elseif "osx" == _OPTIONS["gcc"] then
if os.is("linux") then
- local osxToolchain = "x86_64-apple-darwin13-"
+ local osxToolchain = "x86_64-apple-darwin15-"
premake.gcc.cc = osxToolchain .. "clang"
premake.gcc.cxx = osxToolchain .. "clang++"
premake.gcc.ar = osxToolchain .. "ar"
diff --git a/3rdparty/bx/scripts/unittest++.lua b/3rdparty/bx/scripts/unittest++.lua
deleted file mode 100644
index cf183c1f2f0..00000000000
--- a/3rdparty/bx/scripts/unittest++.lua
+++ /dev/null
@@ -1,30 +0,0 @@
---
--- Copyright 2010-2016 Branimir Karadzic. All rights reserved.
--- License: https://github.com/bkaradzic/bx#license-bsd-2-clause
---
-
-project "UnitTest++"
- kind "StaticLib"
-
- removeflags {
- "NoExceptions",
- }
-
- files {
- "../3rdparty/UnitTest++/src/*.cpp",
- "../3rdparty/UnitTest++/src/*.h",
- }
-
- configuration { "linux or osx or android-* or *nacl* or ps4 or rpi or riscv" }
- files {
- "../3rdparty/UnitTest++/src/Posix/**.cpp",
- "../3rdparty/UnitTest++/src/Posix/**.h",
- }
-
- configuration { "mingw* or vs*" }
- files {
- "../3rdparty/UnitTest++/src/Win32/**.cpp",
- "../3rdparty/UnitTest++/src/Win32/**.h",
- }
-
- configuration {}
diff --git a/3rdparty/bx/tests/main.cpp b/3rdparty/bx/tests/main.cpp
index 3fed5a015ed..f6aaa90d538 100644
--- a/3rdparty/bx/tests/main.cpp
+++ b/3rdparty/bx/tests/main.cpp
@@ -3,38 +3,15 @@
* License: https://github.com/bkaradzic/bx#license-bsd-2-clause
*/
-/*
- * Copyright 2012 Matthew Endsley
- * All rights reserved
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted providing that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
- * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-
+#define CATCH_CONFIG_RUNNER
#include "test.h"
-int runAllTests()
+static const char* s_argv[] = { "bx.test" };
+
+int runAllTests(int _argc, const char* _argv[])
{
DBG(BX_COMPILER_NAME " / " BX_CPU_NAME " / " BX_ARCH_NAME " / " BX_PLATFORM_NAME);
- return UnitTest::RunAllTests();
+ return Catch::Session().run(_argc, _argv);
}
#if BX_PLATFORM_ANDROID
@@ -42,7 +19,7 @@ int runAllTests()
void ANativeActivity_onCreate(ANativeActivity*, void*, size_t)
{
- exit(runAllTests() );
+ exit(runAllTests(BX_COUNTOF(s_argv), s_argv) );
}
#elif BX_PLATFORM_NACL
# include <ppapi/c/pp_errors.h>
@@ -56,7 +33,7 @@ PP_EXPORT const void* PPP_GetInterface(const char* /*_name*/)
PP_EXPORT int32_t PPP_InitializeModule(PP_Module /*_module*/, PPB_GetInterface /*_interface*/)
{
DBG("PPAPI version: %d", PPAPI_RELEASE);
- runAllTests();
+ runAllTests(BX_COUNTOF(s_argv), s_argv);
return PP_ERROR_NOINTERFACE;
}
@@ -64,8 +41,8 @@ PP_EXPORT void PPP_ShutdownModule()
{
}
#else
-int main()
+int main(int _argc, const char* _argv[])
{
- return runAllTests();
+ return runAllTests(_argc, _argv);
}
#endif // BX_PLATFORM
diff --git a/3rdparty/bx/tests/test.h b/3rdparty/bx/tests/test.h
index 8aa4e03ec4c..8fb79c2c78b 100644
--- a/3rdparty/bx/tests/test.h
+++ b/3rdparty/bx/tests/test.h
@@ -7,7 +7,10 @@
#define __TEST_H__
#include <bx/bx.h>
-#include <UnitTest++.h>
+#include <catch/catch.hpp>
+#define TEST(_x) TEST_CASE(#_x, "")
+#define CHECK_EQUAL(_x, _y) REQUIRE(_x == _y)
+
#include "dbg.h"
#if !BX_COMPILER_MSVC
diff --git a/3rdparty/bx/tests/unordered_set_copyctor.cpp b/3rdparty/bx/tests/unordered_set_copyctor.cpp
index 621df020772..3e88304f912 100644
--- a/3rdparty/bx/tests/unordered_set_copyctor.cpp
+++ b/3rdparty/bx/tests/unordered_set_copyctor.cpp
@@ -28,7 +28,6 @@
#include <tinystl/allocator.h>
#include <tinystl/unordered_set.h>
-#include <UnitTest++.h>
TEST(uoset_copyctor) {
diff --git a/3rdparty/bx/tests/unordered_set_pod.cpp b/3rdparty/bx/tests/unordered_set_pod.cpp
index ed408401f7e..a9d8867fd2f 100644
--- a/3rdparty/bx/tests/unordered_set_pod.cpp
+++ b/3rdparty/bx/tests/unordered_set_pod.cpp
@@ -28,7 +28,6 @@
#include <tinystl/allocator.h>
#include <tinystl/unordered_set.h>
-#include <UnitTest++.h>
TEST(uoset_pod_compiles) {
diff --git a/3rdparty/bx/tools/bin/darwin/genie b/3rdparty/bx/tools/bin/darwin/genie
index 54b5fcd9ca5..7f89441c31b 100755
--- a/3rdparty/bx/tools/bin/darwin/genie
+++ b/3rdparty/bx/tools/bin/darwin/genie
Binary files differ
diff --git a/3rdparty/bx/tools/bin/linux/genie b/3rdparty/bx/tools/bin/linux/genie
index 2a498c42bf1..da13d4b8c3e 100755
--- a/3rdparty/bx/tools/bin/linux/genie
+++ b/3rdparty/bx/tools/bin/linux/genie
Binary files differ
diff --git a/3rdparty/bx/tools/bin/windows/genie.exe b/3rdparty/bx/tools/bin/windows/genie.exe
index 85f9260c388..57a6116bea0 100644
--- a/3rdparty/bx/tools/bin/windows/genie.exe
+++ b/3rdparty/bx/tools/bin/windows/genie.exe
Binary files differ