New unit_test framework:

* Header-only!
* No external dependencies or other beast modules
* Compilation options allow for:
  - Stand-alone application to run a single test suite
  - Stand-alone application to run a set of test suites
  - Global suite of tests inline with the host application
  - Disable test suite generation completely
* Existing tests reworked to use the new classes
This commit is contained in:
Vinnie Falco
2014-03-20 17:25:39 -07:00
parent 0bb6171a85
commit f63cf33118
114 changed files with 3259 additions and 4312 deletions

View File

@@ -27,6 +27,19 @@
@file BeastConfig.h
*/
//------------------------------------------------------------------------------
//
// Unit Tests
//
//------------------------------------------------------------------------------
/** Config: BEAST_NO_UNIT_TEST_INLINE
Prevents unit test definitions from being inserted into a global table.
*/
#ifndef BEAST_NO_UNIT_TEST_INLINE
#define BEAST_NO_UNIT_TEST_INLINE 0
#endif
//------------------------------------------------------------------------------
//
// Diagnostics

View File

@@ -93,6 +93,7 @@
<ClInclude Include="..\..\beast\boost\ErrorCode.h" />
<ClInclude Include="..\..\beast\ByteOrder.h" />
<ClInclude Include="..\..\beast\chrono\abstract_clock.h" />
<ClInclude Include="..\..\beast\chrono\abstract_clock_io.h" />
<ClInclude Include="..\..\beast\chrono\basic_seconds_clock.h" />
<ClInclude Include="..\..\beast\chrono\chrono_io.h" />
<ClInclude Include="..\..\beast\chrono\chrono_util.h" />
@@ -224,6 +225,24 @@
<ClInclude Include="..\..\beast\threads\WaitableEvent.h" />
<ClInclude Include="..\..\beast\threads\ScopedWrapperContext.h" />
<ClInclude Include="..\..\beast\Uncopyable.h" />
<ClInclude Include="..\..\beast\unit_test.h" />
<ClInclude Include="..\..\beast\unit_test\amount.h" />
<ClInclude Include="..\..\beast\unit_test\define_print.cpp">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
</ClInclude>
<ClInclude Include="..\..\beast\unit_test\global_suites.h" />
<ClInclude Include="..\..\beast\unit_test\print.h" />
<ClInclude Include="..\..\beast\unit_test\results.h" />
<ClInclude Include="..\..\beast\unit_test\runner.h" />
<ClInclude Include="..\..\beast\unit_test\recorder.h" />
<ClInclude Include="..\..\beast\unit_test\reporter.h" />
<ClInclude Include="..\..\beast\unit_test\match.h" />
<ClInclude Include="..\..\beast\unit_test\suite.h" />
<ClInclude Include="..\..\beast\unit_test\suite_info.h" />
<ClInclude Include="..\..\beast\unit_test\suite_list.h" />
<ClInclude Include="..\..\beast\utility\Debug.h" />
<ClInclude Include="..\..\beast\utility\empty_base_optimization.h" />
<ClInclude Include="..\..\beast\utility\Error.h" />
@@ -284,7 +303,6 @@
<ClInclude Include="..\..\modules\beast_core\diagnostic\FatalError.h" />
<ClInclude Include="..\..\modules\beast_core\diagnostic\SemanticVersion.h" />
<ClInclude Include="..\..\modules\beast_core\diagnostic\Throw.h" />
<ClInclude Include="..\..\modules\beast_core\diagnostic\UnitTest.h" />
<ClInclude Include="..\..\modules\beast_core\diagnostic\UnitTestUtilities.h" />
<ClInclude Include="..\..\modules\beast_core\diagnostic\MeasureFunctionCallTime.h" />
<ClInclude Include="..\..\modules\beast_core\files\DirectoryIterator.h" />
@@ -300,7 +318,6 @@
<ClInclude Include="..\..\modules\beast_core\maths\Range.h" />
<ClInclude Include="..\..\modules\beast_core\memory\MemoryBlock.h" />
<ClInclude Include="..\..\modules\beast_core\memory\SharedSingleton.h" />
<ClInclude Include="..\..\modules\beast_core\misc\Main.h" />
<ClInclude Include="..\..\modules\beast_core\misc\Result.h" />
<ClInclude Include="..\..\modules\beast_core\misc\WindowsRegistry.h" />
<ClInclude Include="..\..\modules\beast_core\native\BasicNativeHeaders.h" />
@@ -380,7 +397,7 @@
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\beast\asio\tests\bind_handler_tests.cpp">
<ClCompile Include="..\..\beast\asio\tests\bind_handler.test.cpp">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
@@ -392,13 +409,13 @@
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\beast\asio\tests\shared_handler_tests.cpp">
<ClCompile Include="..\..\beast\asio\tests\shared_handler.test.cpp">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\beast\asio\tests\wrap_handler_tests.cpp">
<ClCompile Include="..\..\beast\asio\tests\wrap_handler.test.cpp">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
@@ -406,38 +423,32 @@
</ClCompile>
<ClCompile Include="..\..\beast\boost\Boost.cpp" />
<ClCompile Include="..\..\beast\chrono\Chrono.cpp" />
<ClCompile Include="..\..\beast\chrono\impl\basic_seconds_clock.cpp">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\beast\chrono\impl\chrono_io.cpp">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\beast\chrono\impl\CPUMeter.cpp">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\beast\chrono\impl\abstract_clock.cpp">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\beast\chrono\impl\RelativeTime.cpp">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\beast\chrono\tests\abstract_clock.test.cpp">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\beast\chrono\tests\basic_seconds_clock.test.cpp">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\beast\container\Container.cpp" />
<ClCompile Include="..\..\beast\container\impl\aged_associative_container.cpp">
<ClCompile Include="..\..\beast\container\tests\aged_associative_container.test.cpp">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
@@ -450,12 +461,6 @@
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\beast\crypto\Crypto.cpp" />
<ClCompile Include="..\..\beast\crypto\impl\BinaryEncoding.cpp">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\beast\crypto\impl\MurmurHash.cpp">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
@@ -492,6 +497,18 @@
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\beast\crypto\tests\BinaryEncoding.test.cpp">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\beast\crypto\tests\UnsignedInteger.test.cpp">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\beast\cxx14\cxx14.cpp" />
<ClCompile Include="..\..\beast\cxx14\tests\integer_sequence.test.cpp">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
@@ -548,6 +565,12 @@
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\beast\http\tests\ParsedURL.test.cpp">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\beast\insight\impl\Collector.cpp">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
@@ -597,12 +620,6 @@
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\beast\net\impl\IPAddress.cpp">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\beast\net\impl\IPAddressV4.cpp">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
@@ -622,8 +639,19 @@
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\beast\net\Net.cpp" />
<ClCompile Include="..\..\beast\smart_ptr\SmartPtr.cpp" />
<ClCompile Include="..\..\beast\net\tests\IPEndpoint.test.cpp">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\beast\streams\streams.cpp" />
<ClCompile Include="..\..\beast\streams\tests\basic_abstract_ostream.test.cpp">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\beast\strings\impl\CharacterFunctions.cpp">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
@@ -637,12 +665,6 @@
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\beast\strings\Strings.cpp" />
<ClCompile Include="..\..\beast\threads\impl\Atomic.cpp">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\beast\threads\impl\RecursiveMutex.cpp">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
@@ -673,13 +695,19 @@
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\beast\threads\Threads.cpp" />
<ClCompile Include="..\..\beast\utility\impl\Assert.cpp">
<ClCompile Include="..\..\beast\threads\tests\Atomic.test.cpp">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\beast\threads\tests\ServiceQueue.test.cpp">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\beast\threads\Threads.cpp" />
<ClCompile Include="..\..\beast\utility\impl\Debug.cpp">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
@@ -716,6 +744,12 @@
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\beast\utility\tests\bassert.test.cpp">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\beast\utility\tests\empty_base_optimization.test.cpp">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
@@ -800,12 +834,6 @@
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\modules\beast_asio\system\BoostUnitTests.cpp">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\modules\beast_asio\tests\TestPeerLogic.cpp">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
@@ -871,12 +899,6 @@
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\modules\beast_core\diagnostic\UnitTest.cpp">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\modules\beast_core\diagnostic\UnitTestUtilities.cpp">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
@@ -943,12 +965,6 @@
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\modules\beast_core\misc\Main.cpp">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\modules\beast_core\misc\Result.cpp">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
@@ -1285,7 +1301,7 @@
</PrecompiledHeader>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories>$(ProjectDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<DisableLanguageExtensions>false</DisableLanguageExtensions>
<RuntimeTypeInfo>true</RuntimeTypeInfo>
</ClCompile>

View File

@@ -264,9 +264,6 @@
<Filter Include="beast\container">
<UniqueIdentifier>{48c7ee12-704c-42cb-99ea-9a486bb4b57e}</UniqueIdentifier>
</Filter>
<Filter Include="beast\container\impl">
<UniqueIdentifier>{e30eda19-95b4-4831-b86a-ee5fae88abd2}</UniqueIdentifier>
</Filter>
<Filter Include="beast\container\detail">
<UniqueIdentifier>{a4dca8cc-7d1f-4353-b7e1-15eab33e8bd4}</UniqueIdentifier>
</Filter>
@@ -291,6 +288,27 @@
<Filter Include="beast\utility\tests">
<UniqueIdentifier>{3c58ba5e-1855-4865-8a9f-c0afd5014e74}</UniqueIdentifier>
</Filter>
<Filter Include="beast\unit_test">
<UniqueIdentifier>{09aa885d-9607-4f8c-80d2-43673e541fd0}</UniqueIdentifier>
</Filter>
<Filter Include="beast\chrono\tests">
<UniqueIdentifier>{afec071b-bc2c-4d32-a5e3-e99273a81a1c}</UniqueIdentifier>
</Filter>
<Filter Include="beast\crypto\tests">
<UniqueIdentifier>{3e1fc57f-e3c0-4889-a1d8-25145aa535a1}</UniqueIdentifier>
</Filter>
<Filter Include="beast\threads\tests">
<UniqueIdentifier>{1e86eefc-51b3-4270-b472-dd3f323e9875}</UniqueIdentifier>
</Filter>
<Filter Include="beast\http\tests">
<UniqueIdentifier>{a8c4a672-6264-45a5-8c22-e3ce2391300e}</UniqueIdentifier>
</Filter>
<Filter Include="beast\net\tests">
<UniqueIdentifier>{94cc3672-688a-46e4-8df0-c3523a521c43}</UniqueIdentifier>
</Filter>
<Filter Include="beast\streams\tests">
<UniqueIdentifier>{63c495fa-b6b2-42ed-8ae3-9f3582e76bf5}</UniqueIdentifier>
</Filter>
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\..\modules\beast_core\beast_core.h">
@@ -416,9 +434,6 @@
<ClInclude Include="..\..\modules\beast_core\diagnostic\Throw.h">
<Filter>beast_core\diagnostic</Filter>
</ClInclude>
<ClInclude Include="..\..\modules\beast_core\diagnostic\UnitTest.h">
<Filter>beast_core\diagnostic</Filter>
</ClInclude>
<ClInclude Include="..\..\modules\beast_core\files\RandomAccessFile.h">
<Filter>beast_core\files</Filter>
</ClInclude>
@@ -656,9 +671,6 @@
<ClInclude Include="..\..\modules\beast_core\time\AtExitHook.h">
<Filter>beast_core\time</Filter>
</ClInclude>
<ClInclude Include="..\..\modules\beast_core\misc\Main.h">
<Filter>beast_core\misc</Filter>
</ClInclude>
<ClInclude Include="..\..\modules\beast_core\diagnostic\FatalError.h">
<Filter>beast_core\diagnostic</Filter>
</ClInclude>
@@ -749,9 +761,6 @@
<ClInclude Include="..\..\beast\Arithmetic.h">
<Filter>beast</Filter>
</ClInclude>
<ClInclude Include="..\..\beast\Memory.h">
<Filter>beast</Filter>
</ClInclude>
<ClInclude Include="..\..\beast\ByteOrder.h">
<Filter>beast</Filter>
</ClInclude>
@@ -1170,6 +1179,54 @@
<ClInclude Include="..\..\beast\streams\debug_ostream.h">
<Filter>beast\streams</Filter>
</ClInclude>
<ClInclude Include="..\..\beast\unit_test\global_suites.h">
<Filter>beast\unit_test</Filter>
</ClInclude>
<ClInclude Include="..\..\beast\unit_test\runner.h">
<Filter>beast\unit_test</Filter>
</ClInclude>
<ClInclude Include="..\..\beast\unit_test\suite.h">
<Filter>beast\unit_test</Filter>
</ClInclude>
<ClInclude Include="..\..\beast\unit_test\suite_info.h">
<Filter>beast\unit_test</Filter>
</ClInclude>
<ClInclude Include="..\..\beast\unit_test\suite_list.h">
<Filter>beast\unit_test</Filter>
</ClInclude>
<ClInclude Include="..\..\beast\unit_test.h">
<Filter>beast</Filter>
</ClInclude>
<ClInclude Include="..\..\beast\unit_test\results.h">
<Filter>beast\unit_test</Filter>
</ClInclude>
<ClInclude Include="..\..\beast\Memory.h">
<Filter>beast</Filter>
</ClInclude>
<ClInclude Include="..\..\beast\unit_test\reporter.h">
<Filter>beast\unit_test</Filter>
</ClInclude>
<ClInclude Include="..\..\beast\container\const_container.h">
<Filter>beast\container</Filter>
</ClInclude>
<ClInclude Include="..\..\beast\unit_test\recorder.h">
<Filter>beast\unit_test</Filter>
</ClInclude>
<ClInclude Include="..\..\beast\unit_test\amount.h">
<Filter>beast\unit_test</Filter>
</ClInclude>
<ClInclude Include="..\..\beast\unit_test\print.h">
<Filter>beast\unit_test</Filter>
</ClInclude>
<ClInclude Include="..\..\beast\unit_test\match.h">
<Filter>beast\unit_test</Filter>
</ClInclude>
<ClInclude Include="..\..\beast\chrono\abstract_clock_io.h">
<Filter>beast\chrono</Filter>
</ClInclude>
<ClInclude Include="..\..\beast\unit_test\define_print.cpp">
<Filter>beast\unit_test</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="..\..\modules\beast_core\files\DirectoryIterator.cpp">
@@ -1274,9 +1331,6 @@
<ClCompile Include="..\..\modules\beast_core\native\bsd_Threads.cpp">
<Filter>beast_core\native</Filter>
</ClCompile>
<ClCompile Include="..\..\modules\beast_core\diagnostic\UnitTest.cpp">
<Filter>beast_core\diagnostic</Filter>
</ClCompile>
<ClCompile Include="..\..\modules\beast_core\files\RandomAccessFile.cpp">
<Filter>beast_core\files</Filter>
</ClCompile>
@@ -1355,9 +1409,6 @@
<ClCompile Include="..\..\modules\beast_asio\basics\PeerRole.cpp">
<Filter>beast_asio\basics</Filter>
</ClCompile>
<ClCompile Include="..\..\modules\beast_asio\system\BoostUnitTests.cpp">
<Filter>beast_asio\system</Filter>
</ClCompile>
<ClCompile Include="..\..\modules\beast_asio\tests\PeerTest.cpp">
<Filter>beast_asio\tests</Filter>
</ClCompile>
@@ -1418,9 +1469,6 @@
<ClCompile Include="..\..\modules\beast_core\time\AtExitHook.cpp">
<Filter>beast_core\time</Filter>
</ClCompile>
<ClCompile Include="..\..\modules\beast_core\misc\Main.cpp">
<Filter>beast_core\misc</Filter>
</ClCompile>
<ClCompile Include="..\..\modules\beast_core\diagnostic\FatalError.cpp">
<Filter>beast_core\diagnostic</Filter>
</ClCompile>
@@ -1499,15 +1547,6 @@
<ClCompile Include="..\..\modules\beast_asio\http\HTTPResponseParser.cpp">
<Filter>beast_asio\http</Filter>
</ClCompile>
<ClCompile Include="..\..\beast\chrono\impl\CPUMeter.cpp">
<Filter>beast\chrono\impl</Filter>
</ClCompile>
<ClCompile Include="..\..\beast\smart_ptr\SmartPtr.cpp">
<Filter>beast\smart_ptr</Filter>
</ClCompile>
<ClCompile Include="..\..\beast\threads\impl\Atomic.cpp">
<Filter>beast\threads\impl</Filter>
</ClCompile>
<ClCompile Include="..\..\beast\threads\impl\RecursiveMutex.cpp">
<Filter>beast\threads\impl</Filter>
</ClCompile>
@@ -1565,15 +1604,6 @@
<ClCompile Include="..\..\beast\insight\impl\Hook.cpp">
<Filter>beast\insight\impl</Filter>
</ClCompile>
<ClCompile Include="..\..\beast\chrono\impl\abstract_clock.cpp">
<Filter>beast\chrono\impl</Filter>
</ClCompile>
<ClCompile Include="..\..\beast\chrono\impl\chrono_io.cpp">
<Filter>beast\chrono\impl</Filter>
</ClCompile>
<ClCompile Include="..\..\beast\crypto\impl\BinaryEncoding.cpp">
<Filter>beast\crypto\impl</Filter>
</ClCompile>
<ClCompile Include="..\..\beast\crypto\impl\UnsignedInteger.cpp">
<Filter>beast\crypto\impl</Filter>
</ClCompile>
@@ -1583,9 +1613,6 @@
<ClCompile Include="..\..\beast\insight\impl\Groups.cpp">
<Filter>beast\insight\impl</Filter>
</ClCompile>
<ClCompile Include="..\..\beast\net\impl\IPAddress.cpp">
<Filter>beast\net\impl</Filter>
</ClCompile>
<ClCompile Include="..\..\beast\net\impl\IPAddressV4.cpp">
<Filter>beast\net\impl</Filter>
</ClCompile>
@@ -1595,21 +1622,12 @@
<ClCompile Include="..\..\beast\net\impl\IPEndpoint.cpp">
<Filter>beast\net\impl</Filter>
</ClCompile>
<ClCompile Include="..\..\beast\utility\impl\Assert.cpp">
<Filter>beast\utility\impl</Filter>
</ClCompile>
<ClCompile Include="..\..\beast\chrono\Chrono.cpp">
<Filter>beast\chrono</Filter>
</ClCompile>
<ClCompile Include="..\..\beast\chrono\impl\basic_seconds_clock.cpp">
<Filter>beast\chrono\impl</Filter>
</ClCompile>
<ClCompile Include="..\..\beast\container\Container.cpp">
<Filter>beast\container</Filter>
</ClCompile>
<ClCompile Include="..\..\beast\container\impl\aged_associative_container.cpp">
<Filter>beast\container\impl</Filter>
</ClCompile>
<ClCompile Include="..\..\beast\container\tests\buffer_view.test.cpp">
<Filter>beast\container\tests</Filter>
</ClCompile>
@@ -1622,15 +1640,6 @@
<ClCompile Include="..\..\beast\asio\abstract_socket.cpp">
<Filter>beast\asio</Filter>
</ClCompile>
<ClCompile Include="..\..\beast\asio\tests\bind_handler_tests.cpp">
<Filter>beast\asio\tests</Filter>
</ClCompile>
<ClCompile Include="..\..\beast\asio\tests\shared_handler_tests.cpp">
<Filter>beast\asio\tests</Filter>
</ClCompile>
<ClCompile Include="..\..\beast\asio\tests\wrap_handler_tests.cpp">
<Filter>beast\asio\tests</Filter>
</ClCompile>
<ClCompile Include="..\..\beast\asio\tests\enable_wait_for_async.test.cpp">
<Filter>beast\asio\tests</Filter>
</ClCompile>
@@ -1640,11 +1649,56 @@
<ClCompile Include="..\..\beast\http\impl\joyent_parser.cpp">
<Filter>beast\http\impl</Filter>
</ClCompile>
<ClCompile Include="..\..\beast\utility\tests\empty_base_optimization.test.cpp">
<Filter>beast\utility\tests</Filter>
</ClCompile>
<ClCompile Include="..\..\beast\container\tests\aged_associative_container.test.cpp">
<Filter>beast\container\tests</Filter>
</ClCompile>
<ClCompile Include="..\..\beast\asio\tests\bind_handler.test.cpp">
<Filter>beast\asio\tests</Filter>
</ClCompile>
<ClCompile Include="..\..\beast\asio\tests\shared_handler.test.cpp">
<Filter>beast\asio\tests</Filter>
</ClCompile>
<ClCompile Include="..\..\beast\asio\tests\wrap_handler.test.cpp">
<Filter>beast\asio\tests</Filter>
</ClCompile>
<ClCompile Include="..\..\beast\chrono\tests\abstract_clock.test.cpp">
<Filter>beast\chrono\tests</Filter>
</ClCompile>
<ClCompile Include="..\..\beast\crypto\tests\UnsignedInteger.test.cpp">
<Filter>beast\crypto\tests</Filter>
</ClCompile>
<ClCompile Include="..\..\beast\crypto\tests\BinaryEncoding.test.cpp">
<Filter>beast\crypto\tests</Filter>
</ClCompile>
<ClCompile Include="..\..\beast\utility\tests\bassert.test.cpp">
<Filter>beast\utility\tests</Filter>
</ClCompile>
<ClCompile Include="..\..\beast\threads\tests\ServiceQueue.test.cpp">
<Filter>beast\threads\tests</Filter>
</ClCompile>
<ClCompile Include="..\..\beast\chrono\tests\basic_seconds_clock.test.cpp">
<Filter>beast\chrono\tests</Filter>
</ClCompile>
<ClCompile Include="..\..\beast\chrono\impl\chrono_io.cpp">
<Filter>beast\chrono\impl</Filter>
</ClCompile>
<ClCompile Include="..\..\beast\http\tests\ParsedURL.test.cpp">
<Filter>beast\http\tests</Filter>
</ClCompile>
<ClCompile Include="..\..\beast\net\tests\IPEndpoint.test.cpp">
<Filter>beast\net\tests</Filter>
</ClCompile>
<ClCompile Include="..\..\beast\streams\tests\basic_abstract_ostream.test.cpp">
<Filter>beast\streams\tests</Filter>
</ClCompile>
<ClCompile Include="..\..\beast\streams\streams.cpp">
<Filter>beast\streams</Filter>
</ClCompile>
<ClCompile Include="..\..\beast\utility\tests\empty_base_optimization.test.cpp">
<Filter>beast\utility\tests</Filter>
<ClCompile Include="..\..\beast\threads\tests\Atomic.test.cpp">
<Filter>beast\threads\tests</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>

View File

@@ -23,10 +23,10 @@
#include "impl/IPAddressConversion.cpp"
#include "tests/wrap_handler_tests.cpp"
#include "tests/bind_handler_tests.cpp"
#include "tests/wrap_handler.test.cpp"
#include "tests/bind_handler.test.cpp"
#include "tests/enable_wait_for_async.test.cpp"
#include "tests/shared_handler_tests.cpp"
#include "tests/shared_handler.test.cpp"
#include "abstract_socket.cpp" // TEMPORARY!

View File

@@ -21,7 +21,7 @@
#include "../../../BeastConfig.h"
#endif
#include "../../../modules/beast_core/beast_core.h" // for UnitTest
#include "../../unit_test/suite.h"
#include "../bind_handler.h"
@@ -30,31 +30,24 @@
namespace beast {
namespace asio {
class bind_handler_Tests : public UnitTest
class bind_handler_test : public unit_test::suite
{
public:
static void foo (int)
{
}
void runTest()
void run()
{
beginTestCase ("call");
auto f (bind_handler (std::bind (&foo, std::placeholders::_1),
auto f (bind_handler (
std::bind (&foo, std::placeholders::_1),
42));
f();
pass();
}
bind_handler_Tests() : UnitTest ("bind_handler", "beast", runManual)
{
}
};
static bind_handler_Tests bind_handler_tests;
BEAST_DEFINE_TESTSUITE(bind_handler,asio,beast);
}
}

View File

@@ -21,7 +21,7 @@
#include "../../../BeastConfig.h"
#endif
#include "../../../modules/beast_core/beast_core.h" // for UnitTest
#include "../../unit_test/suite.h"
#include "../bind_handler.h"
#include "../enable_wait_for_async.h"
@@ -30,7 +30,7 @@
namespace beast {
class enable_wait_for_async_Tests : public UnitTest
class enable_wait_for_async_test : public unit_test::suite
{
public:
typedef boost::system::error_code error_code;
@@ -89,22 +89,17 @@ public:
}
};
beginTestCase ("wait_for_async");
owner o;
o();
expect (o.notified);
}
void runTest()
void run()
{
test();
}
enable_wait_for_async_Tests() : UnitTest ("enable_wait_for_async", "beast")
{
}
};
static enable_wait_for_async_Tests enable_wait_for_async_tests;
BEAST_DEFINE_TESTSUITE(enable_wait_for_async,asio,beast);
}

View File

@@ -21,7 +21,7 @@
#include "../../../BeastConfig.h"
#endif
#include "../../../modules/beast_core/beast_core.h" // for UnitTest
#include "../../unit_test/suite.h"
#include "../shared_handler.h"
@@ -37,7 +37,7 @@
namespace beast {
class shared_handler_Tests : public UnitTest
class shared_handler_test : public unit_test::suite
{
public:
struct test_results
@@ -139,10 +139,8 @@ public:
async_op (handler);
}
void runTest()
void run()
{
beginTestCase ("hooks");
#if ! BEAST_NO_STD_FUNCTION_CONSTRUCTIBLE
static_assert (! std::is_constructible <
std::function <void(void)>, int&&>::value,
@@ -230,12 +228,8 @@ public:
expect (r.cont);
}
}
shared_handler_Tests() : UnitTest ("shared_handler", "beast")
{
}
};
static shared_handler_Tests shared_handler_tests;
BEAST_DEFINE_TESTSUITE(shared_handler,asio,beast);
}

View File

@@ -21,7 +21,7 @@
#include "../../../BeastConfig.h"
#endif
#include "../../../modules/beast_core/beast_core.h" // for UnitTest
#include "../../unit_test/suite.h"
#include "../wrap_handler.h"
@@ -38,7 +38,7 @@ namespace asio {
// Displays the order of destruction of parameters in the bind wrapper
//
class boost_bind_Tests : public UnitTest
class boost_bind_test : public unit_test::suite
{
public:
struct Result
@@ -84,10 +84,8 @@ public:
{
}
void runTest()
void run()
{
beginTestCase ("order");
{
Result r;
{
@@ -96,7 +94,8 @@ public:
Arg (r, "two"),
Arg (r, "three"));
}
logMessage (std::string ("boost::bind (") + r.text + ")");
log <<
std::string ("boost::bind (") + r.text + ")";
}
{
@@ -107,22 +106,20 @@ public:
Arg (r, "two"),
Arg (r, "three"));
}
logMessage (std::string ("std::bind (") + r.text + ")");
log <<
std::string ("std::bind (") + r.text + ")";
}
pass();
}
boost_bind_Tests() : UnitTest ("bind", "beast", runManual)
{
}
};
static boost_bind_Tests boost_bind_tests;
BEAST_DEFINE_TESTSUITE(boost_bind,asio,beast);
//------------------------------------------------------------------------------
class wrap_handler_handler_Tests : public UnitTest
class wrap_handler_test : public unit_test::suite
{
public:
struct test_results
@@ -218,10 +215,8 @@ public:
return boost_asio_handler_cont_helpers::is_continuation (handler);
}
void runTest()
void run()
{
beginTestCase ("hooks");
// Hooks called when using the raw handler
{
test_results r;
@@ -276,13 +271,9 @@ public:
expect (f.call);
}
}
wrap_handler_handler_Tests() : UnitTest ("wrap_handler", "beast")
{
}
};
static wrap_handler_handler_Tests wrap_handler_handler_tests;
BEAST_DEFINE_TESTSUITE(wrap_handler,asio,beast);
}
}

View File

@@ -22,10 +22,9 @@
#endif
#include "../Config.h"
#include "../../modules/beast_core/beast_core.h" // for UnitTest
#include "impl/abstract_clock.cpp"
#include "impl/chrono_io.cpp"
#include "impl/basic_seconds_clock.cpp"
#include "impl/RelativeTime.cpp"
#include "tests/abstract_clock.test.cpp"
#include "tests/basic_seconds_clock.test.cpp"

View File

@@ -20,8 +20,6 @@
#ifndef BEAST_CHRONO_ABSTRACT_CLOCK_H_INCLUDED
#define BEAST_CHRONO_ABSTRACT_CLOCK_H_INCLUDED
#include "chrono_io.h"
#include <chrono>
#include <string>
@@ -75,9 +73,10 @@ public:
/** Returns the current time. */
virtual time_point now () const = 0;
#if 0
/** Convert the specified time point to a string. */
/** @{ */
virtual std::string to_string (time_point const& tp) const = 0;
//virtual std::string to_string (time_point const& tp) const = 0;
template <class Duration2>
std::string to_string (
@@ -87,6 +86,7 @@ public:
std::chrono::time_point_cast <Duration> (tp));
}
/** @} */
#endif
/** Returning elapsed ticks since the epoch. */
rep elapsed () const
@@ -123,6 +123,7 @@ struct abstract_clock_wrapper
: public basic_abstract_clock_wrapper <TrivialClock, Duration>
{
// generic conversion displays the duration
/*
std::string to_string (typename basic_abstract_clock_wrapper <
TrivialClock, Duration>::time_point const& tp) const
{
@@ -130,6 +131,7 @@ struct abstract_clock_wrapper
ss << tp.time_since_epoch();
return ss.str ();
}
*/
};
/*

View File

@@ -17,30 +17,21 @@
*/
//==============================================================================
#include "../basic_seconds_clock.h"
#ifndef BEAST_CHRONO_ABSTRACT_CLOCK_IO_H_INCLUDED
#define BEAST_CHRONO_ABSTRACT_CLOCK_IO_H_INCLUDED
#include "../../Config.h"
#include "../../../modules/beast_core/beast_core.h" // for UnitTest
#include "chrono_io.h"
namespace beast {
class basic_seconds_clock_Tests : public UnitTest
template <class CharT, class Traits, class Duration, class Resolution>
std::basic_ostream <CharT, Traits>&
operator<< (std::basic_ostream <CharT, Traits>& os,
std::chrono::time_point <abstract_clock <Resolution>, Duration> const& tp)
{
public:
void runTest ()
{
beginTestCase ("now");
basic_seconds_clock <std::chrono::steady_clock>::now ();
pass ();
}
basic_seconds_clock_Tests() : UnitTest("basic_seconds_clock", "beast")
{
}
};
static basic_seconds_clock_Tests basic_seconds_clock_tests;
return os << tp.time_since_epoch() << " since epoch";
}
}
#endif

View File

@@ -53,12 +53,14 @@ public:
return m_now;
}
#if 0
std::string to_string (time_point const& tp) const
{
std::stringstream ss;
ss << tp.time_since_epoch() << " from start";
return ss.str ();
}
#endif
/** Set the current time of the manual clock.
Precondition:

View File

@@ -18,16 +18,18 @@
//==============================================================================
#include "../abstract_clock.h"
#include "../abstract_clock_io.h"
#include "../manual_clock.h"
#include <thread>
#include "../../unit_test/suite.h"
#include <string>
#include <sstream>
#include <string>
#include <thread>
namespace beast {
class abstract_clock_tests : public UnitTest
class abstract_clock_test : public unit_test::suite
{
public:
void test (abstract_clock <std::chrono::seconds>& c)
@@ -40,10 +42,10 @@ public:
std::stringstream ss;
ss <<
"t1= " << c.to_string (t1) <<
", t2= " << c.to_string (t2) <<
"t1= " << t1.time_since_epoch() <<
", t2= " << t2.time_since_epoch() <<
", elapsed= " << (t2 - t1);
logMessage (ss.str());
log << ss.str();
}
}
@@ -54,45 +56,38 @@ public:
std::stringstream ss;
ss << "now() = " << c.to_string (c.now ()) << std::endl;
ss << "now() = " << c.now () << std::endl;
c.set (clock_type::time_point (std::chrono::seconds (1)));
ss << "now() = " << c.to_string (c.now ()) << std::endl;
ss << "now() = " << c.now () << std::endl;
c.set (clock_type::time_point (std::chrono::seconds (2)));
ss << "now() = " << c.to_string (c.now ()) << std::endl;
ss << "now() = " << c.now () << std::endl;
logMessage (ss.str());
log << ss.str();
}
void runTest ()
void run ()
{
beginTestCase ("Syntax");
logMessage ("steady_clock");
log << "steady_clock";
test (get_abstract_clock <std::chrono::steady_clock,
std::chrono::seconds> ());
logMessage ("system_clock");
log << "system_clock";
test (get_abstract_clock <std::chrono::system_clock,
std::chrono::seconds> ());
logMessage ("high_resolution_clock");
log << "high_resolution_clock";
test (get_abstract_clock <std::chrono::high_resolution_clock,
std::chrono::seconds> ());
logMessage ("manual_clock");
log << "manual_clock";
test_manual ();
pass ();
}
abstract_clock_tests ()
: UnitTest ("abstract_clock", "beast", runManual)
{
}
};
static abstract_clock_tests abstract_clock_tests_;
BEAST_DEFINE_TESTSUITE(abstract_clock,chrono,beast);
}

View File

@@ -17,15 +17,24 @@
*/
//==============================================================================
#if BEAST_INCLUDE_BEASTCONFIG
#include "../../BeastConfig.h"
#endif
#include "../../unit_test/suite.h"
#include "../Config.h"
#include "../basic_seconds_clock.h"
#include "ContainerDeletePolicy.h"
#include "ScopedPointer.h"
#include "SharedObject.h"
#include "SharedPtr.h"
namespace beast {
#include "../../modules/beast_core/beast_core.h" // for UnitTest
class basic_seconds_clock_test : public unit_test::suite
{
public:
void
run()
{
basic_seconds_clock <
std::chrono::steady_clock>::now ();
pass ();
}
};
BEAST_DEFINE_TESTSUITE(basic_seconds_clock,chrono,beast);
}

View File

@@ -21,7 +21,5 @@
#include "../../BeastConfig.h"
#endif
#include "impl/aged_associative_container.cpp"
#include "tests/aged_associative_container.test.cpp"
#include "tests/buffer_view.test.cpp"

View File

@@ -22,6 +22,7 @@
#include "../Config.h"
#include <array>
#include "../cxx14/algorithm.h" // <algorithm>
#include <cstddef>
#include <iterator>

View File

@@ -23,9 +23,6 @@
#include "aged_container_iterator.h"
#include "aged_associative_container.h"
#include "../../cxx14/algorithm.h"
#include "../../cxx14/type_traits.h"
#include "../aged_container.h"
#include "../../chrono/abstract_clock.h"
@@ -34,10 +31,12 @@
#include <boost/intrusive/list.hpp>
#include <boost/intrusive/set.hpp>
#include "../../cxx14/algorithm.h" // <algorithm>
#include <functional>
#include <initializer_list>
#include <iterator>
#include <memory>
#include "../../cxx14/type_traits.h" // <type_traits>
#include <utility>
namespace beast {

View File

@@ -31,12 +31,12 @@
#include <boost/intrusive/list.hpp>
#include <boost/intrusive/unordered_set.hpp>
#include "../../cxx14/algorithm.h"
#include "../../cxx14/type_traits.h"
#include "../../cxx14/algorithm.h" // <algorithm>
#include <functional>
#include <initializer_list>
#include <iterator>
#include <memory>
#include "../../cxx14/type_traits.h" // <type_traits>
#include <utility>
/*

View File

@@ -17,8 +17,9 @@
*/
//==============================================================================
#include "../../../modules/beast_core/beast_core.h" // for UnitTest
#include "../../chrono/manual_clock.h"
#include "../../unit_test/suite.h"
#include "../aged_set.h"
#include "../aged_map.h"
#include "../aged_multiset.h"
@@ -28,6 +29,9 @@
#include "../aged_unordered_multiset.h"
#include "../aged_unordered_multimap.h"
#include <vector>
#include <list>
#ifndef BEAST_AGED_UNORDERED_NO_ALLOC_DEFAULTCTOR
# ifdef _MSC_VER
# define BEAST_AGED_UNORDERED_NO_ALLOC_DEFAULTCTOR 0
@@ -46,7 +50,7 @@
namespace beast {
class aged_associative_container_TestsBase : public UnitTest
class aged_associative_container_test_base : public unit_test::suite
{
public:
template <class T>
@@ -392,56 +396,6 @@ public:
//--------------------------------------------------------------------------
// Compile time checks
//
void checkAliases ()
{
typedef std::string Key;
typedef int T;
static_assert (std::is_same <
aged_set <Key>,
detail::aged_ordered_container <false, false, Key, void>>::value,
"bad alias: aged_set");
static_assert (std::is_same <
aged_multiset <Key>,
detail::aged_ordered_container <true, false, Key, void>>::value,
"bad alias: aged_multiset");
static_assert (std::is_same <
aged_map <Key, T>,
detail::aged_ordered_container <false, true, Key, T>>::value,
"bad alias: aged_map");
static_assert (std::is_same <
aged_multimap <Key, T>,
detail::aged_ordered_container <true, true, Key, T>>::value,
"bad alias: aged_multimap");
static_assert (std::is_same <
aged_unordered_set <Key>,
detail::aged_unordered_container <false, false, Key, void>>::value,
"bad alias: aged_unordered_set");
static_assert (std::is_same <
aged_unordered_multiset <Key>,
detail::aged_unordered_container <true, false, Key, void>>::value,
"bad alias: aged_unordered_multiset");
static_assert (std::is_same <
aged_unordered_map <Key, T>,
detail::aged_unordered_container <false, true, Key, T>>::value,
"bad alias: aged_unordered_map");
static_assert (std::is_same <
aged_unordered_multimap <Key, T>,
detail::aged_unordered_container <true, true, Key, T>>::value,
"bad alias: aged_unordered_multimap");
}
//--------------------------------------------------------------------------
template <
class Container,
class Values
@@ -603,11 +557,6 @@ public:
template <bool IsUnordered>
void testMaybeUnordered();
aged_associative_container_TestsBase () : UnitTest (
"aged_associative_container", "beast")
{
}
};
//------------------------------------------------------------------------------
@@ -620,7 +569,7 @@ template <
>
typename std::enable_if <
Container::is_map::value && ! Container::is_multi::value>::type
aged_associative_container_TestsBase::
aged_associative_container_test_base::
checkMapContents (Container& c, Values const& v)
{
if (v.empty())
@@ -651,7 +600,7 @@ template <
>
typename std::enable_if <
std::remove_reference <C>::type::is_unordered::value>::type
aged_associative_container_TestsBase::
aged_associative_container_test_base::
checkUnorderedContentsRefRef (C&& c, Values const& v)
{
typedef typename std::remove_reference <C>::type Cont;
@@ -685,7 +634,7 @@ checkUnorderedContentsRefRef (C&& c, Values const& v)
template <class C, class Values>
void
aged_associative_container_TestsBase::
aged_associative_container_test_base::
checkContentsRefRef (C&& c, Values const& v)
{
typedef typename std::remove_reference <C>::type Cont;
@@ -715,7 +664,7 @@ checkContentsRefRef (C&& c, Values const& v)
template <class Cont, class Values>
void
aged_associative_container_TestsBase::
aged_associative_container_test_base::
checkContents (Cont& c, Values const& v)
{
checkContentsRefRef (c, v);
@@ -725,7 +674,7 @@ checkContents (Cont& c, Values const& v)
template <class Cont>
void
aged_associative_container_TestsBase::
aged_associative_container_test_base::
checkContents (Cont& c)
{
typedef TestTraits <
@@ -746,7 +695,7 @@ checkContents (Cont& c)
// ordered
template <bool IsUnordered, bool IsMulti, bool IsMap>
typename std::enable_if <! IsUnordered>::type
aged_associative_container_TestsBase::
aged_associative_container_test_base::
testConstructEmpty ()
{
typedef TestTraits <IsUnordered, IsMulti, IsMap> Traits;
@@ -760,7 +709,8 @@ testConstructEmpty ()
typedef typename Traits::MyAlloc MyAlloc;
typename Traits::Clock clock;
beginTestCase (Traits::name() + " empty");
//testcase (Traits::name() + " empty");
testcase ("empty");
{
typename Traits::template Cont <Comp, Alloc> c (
@@ -790,7 +740,7 @@ testConstructEmpty ()
// unordered
template <bool IsUnordered, bool IsMulti, bool IsMap>
typename std::enable_if <IsUnordered>::type
aged_associative_container_TestsBase::
aged_associative_container_test_base::
testConstructEmpty ()
{
typedef TestTraits <IsUnordered, IsMulti, IsMap> Traits;
@@ -806,8 +756,8 @@ testConstructEmpty ()
typedef typename Traits::MyAlloc MyAlloc;
typename Traits::Clock clock;
beginTestCase (Traits::name() + " empty");
//testcase (Traits::name() + " empty");
testcase ("empty");
{
typename Traits::template Cont <Hash, Equal, Alloc> c (
clock);
@@ -860,7 +810,7 @@ testConstructEmpty ()
// ordered
template <bool IsUnordered, bool IsMulti, bool IsMap>
typename std::enable_if <! IsUnordered>::type
aged_associative_container_TestsBase::
aged_associative_container_test_base::
testConstructRange ()
{
typedef TestTraits <IsUnordered, IsMulti, IsMap> Traits;
@@ -875,7 +825,8 @@ testConstructRange ()
typename Traits::Clock clock;
auto const v (Traits::values());
beginTestCase (Traits::name() + " range");
//testcase (Traits::name() + " range");
testcase ("range");
{
typename Traits::template Cont <Comp, Alloc> c (
@@ -922,7 +873,7 @@ testConstructRange ()
// unordered
template <bool IsUnordered, bool IsMulti, bool IsMap>
typename std::enable_if <IsUnordered>::type
aged_associative_container_TestsBase::
aged_associative_container_test_base::
testConstructRange ()
{
typedef TestTraits <IsUnordered, IsMulti, IsMap> Traits;
@@ -939,7 +890,8 @@ testConstructRange ()
typename Traits::Clock clock;
auto const v (Traits::values());
beginTestCase (Traits::name() + " range");
//testcase (Traits::name() + " range");
testcase ("range");
{
typename Traits::template Cont <Hash, Equal, Alloc> c (
@@ -1001,7 +953,7 @@ testConstructRange ()
// ordered
template <bool IsUnordered, bool IsMulti, bool IsMap>
typename std::enable_if <! IsUnordered>::type
aged_associative_container_TestsBase::
aged_associative_container_test_base::
testConstructInitList ()
{
typedef TestTraits <IsUnordered, IsMulti, IsMap> Traits;
@@ -1015,7 +967,8 @@ testConstructInitList ()
typedef typename Traits::MyAlloc MyAlloc;
typename Traits::Clock clock;
beginTestCase (Traits::name() + " init-list");
//testcase (Traits::name() + " init-list");
testcase ("init-list");
// VFALCO TODO
@@ -1025,7 +978,7 @@ testConstructInitList ()
// unordered
template <bool IsUnordered, bool IsMulti, bool IsMap>
typename std::enable_if <IsUnordered>::type
aged_associative_container_TestsBase::
aged_associative_container_test_base::
testConstructInitList ()
{
typedef TestTraits <IsUnordered, IsMulti, IsMap> Traits;
@@ -1041,7 +994,9 @@ testConstructInitList ()
typedef typename Traits::MyAlloc MyAlloc;
typename Traits::Clock clock;
beginTestCase (Traits::name() + " init-list");
//testcase (Traits::name() + " init-list");
testcase ("init-list");
// VFALCO TODO
pass();
}
@@ -1054,7 +1009,7 @@ testConstructInitList ()
template <bool IsUnordered, bool IsMulti, bool IsMap>
void
aged_associative_container_TestsBase::
aged_associative_container_test_base::
testCopyMove ()
{
typedef TestTraits <IsUnordered, IsMulti, IsMap> Traits;
@@ -1063,7 +1018,8 @@ testCopyMove ()
typename Traits::Clock clock;
auto const v (Traits::values());
beginTestCase (Traits::name() + " copy/move");
//testcase (Traits::name() + " copy/move");
testcase ("copy/move");
// copy
@@ -1136,7 +1092,7 @@ testCopyMove ()
template <class Container, class Values>
void
aged_associative_container_TestsBase::
aged_associative_container_test_base::
checkInsertCopy (Container& c, Values const& v)
{
for (auto const& e : v)
@@ -1146,7 +1102,7 @@ checkInsertCopy (Container& c, Values const& v)
template <class Container, class Values>
void
aged_associative_container_TestsBase::
aged_associative_container_test_base::
checkInsertMove (Container& c, Values const& v)
{
Values v2 (v);
@@ -1157,7 +1113,7 @@ checkInsertMove (Container& c, Values const& v)
template <class Container, class Values>
void
aged_associative_container_TestsBase::
aged_associative_container_test_base::
checkInsertHintCopy (Container& c, Values const& v)
{
for (auto const& e : v)
@@ -1167,7 +1123,7 @@ checkInsertHintCopy (Container& c, Values const& v)
template <class Container, class Values>
void
aged_associative_container_TestsBase::
aged_associative_container_test_base::
checkInsertHintMove (Container& c, Values const& v)
{
Values v2 (v);
@@ -1178,7 +1134,7 @@ checkInsertHintMove (Container& c, Values const& v)
template <class Container, class Values>
void
aged_associative_container_TestsBase::
aged_associative_container_test_base::
checkEmplace (Container& c, Values const& v)
{
for (auto const& e : v)
@@ -1188,7 +1144,7 @@ checkEmplace (Container& c, Values const& v)
template <class Container, class Values>
void
aged_associative_container_TestsBase::
aged_associative_container_test_base::
checkEmplaceHint (Container& c, Values const& v)
{
for (auto const& e : v)
@@ -1198,7 +1154,7 @@ checkEmplaceHint (Container& c, Values const& v)
template <bool IsUnordered, bool IsMulti, bool IsMap>
void
aged_associative_container_TestsBase::
aged_associative_container_test_base::
testModifiers()
{
typedef TestTraits <IsUnordered, IsMulti, IsMap> Traits;
@@ -1206,7 +1162,8 @@ testModifiers()
auto const v (Traits::values());
auto const l (make_list (v));
beginTestCase (Traits::name() + " modify");
//testcase (Traits::name() + " modify");
testcase ("modify");
{
typename Traits::template Cont <> c (clock);
@@ -1257,7 +1214,7 @@ testModifiers()
template <bool IsUnordered, bool IsMulti, bool IsMap>
void
aged_associative_container_TestsBase::
aged_associative_container_test_base::
testChronological ()
{
typedef TestTraits <IsUnordered, IsMulti, IsMap> Traits;
@@ -1265,7 +1222,8 @@ testChronological ()
typename Traits::Clock clock;
auto const v (Traits::values());
beginTestCase (Traits::name() + " chronological");
//testcase (Traits::name() + " chronological");
testcase ("chronological");
typename Traits::template Cont <> c (
v.begin(), v.end(), clock);
@@ -1297,14 +1255,15 @@ testChronological ()
// map, unordered_map
template <bool IsUnordered, bool IsMulti, bool IsMap>
typename std::enable_if <IsMap && ! IsMulti>::type
aged_associative_container_TestsBase::
aged_associative_container_test_base::
testArrayCreate()
{
typedef TestTraits <IsUnordered, IsMulti, IsMap> Traits;
typename Traits::Clock clock;
auto v (Traits::values());
beginTestCase (Traits::name() + " array create");
//testcase (Traits::name() + " array create");
testcase ("array create");
{
// Copy construct key
@@ -1332,7 +1291,7 @@ testArrayCreate()
// ordered
template <bool IsUnordered, bool IsMulti, bool IsMap>
typename std::enable_if <! IsUnordered>::type
aged_associative_container_TestsBase::
aged_associative_container_test_base::
testCompare ()
{
typedef TestTraits <IsUnordered, IsMulti, IsMap> Traits;
@@ -1340,7 +1299,8 @@ testCompare ()
typename Traits::Clock clock;
auto const v (Traits::values());
beginTestCase (Traits::name() + " array create");
//testcase (Traits::name() + " array create");
testcase ("array create");
typename Traits::template Cont <> c1 (
v.begin(), v.end(), clock);
@@ -1366,13 +1326,14 @@ testCompare ()
// ordered
template <bool IsUnordered, bool IsMulti, bool IsMap>
typename std::enable_if <! IsUnordered>::type
aged_associative_container_TestsBase::
aged_associative_container_test_base::
testObservers()
{
typedef TestTraits <IsUnordered, IsMulti, IsMap> Traits;
typename Traits::Clock clock;
beginTestCase (Traits::name() + " observers");
//testcase (Traits::name() + " observers");
testcase ("observers");
typename Traits::template Cont <> c (clock);
c.key_comp();
@@ -1384,13 +1345,14 @@ testObservers()
// unordered
template <bool IsUnordered, bool IsMulti, bool IsMap>
typename std::enable_if <IsUnordered>::type
aged_associative_container_TestsBase::
aged_associative_container_test_base::
testObservers()
{
typedef TestTraits <IsUnordered, IsMulti, IsMap> Traits;
typename Traits::Clock clock;
beginTestCase (Traits::name() + " observers");
//testcase (Traits::name() + " observers");
testcase ("observers");
typename Traits::template Cont <> c (clock);
c.hash_function();
@@ -1407,7 +1369,7 @@ testObservers()
template <bool IsUnordered, bool IsMulti, bool IsMap>
void
aged_associative_container_TestsBase::
aged_associative_container_test_base::
testMaybeUnorderedMultiMap ()
{
typedef TestTraits <IsUnordered, IsMulti, IsMap> Traits;
@@ -1423,38 +1385,133 @@ testMaybeUnorderedMultiMap ()
testObservers <IsUnordered, IsMulti, IsMap> ();
}
template <bool IsUnordered, bool IsMulti>
void
aged_associative_container_TestsBase::
testMaybeUnorderedMulti()
{
testMaybeUnorderedMultiMap <IsUnordered, IsMulti, false> ();
testMaybeUnorderedMultiMap <IsUnordered, IsMulti, true> ();
}
template <bool IsUnordered>
void
aged_associative_container_TestsBase::
testMaybeUnordered()
{
testMaybeUnorderedMulti <IsUnordered, false> ();
testMaybeUnorderedMulti <IsUnordered, true> ();
}
//------------------------------------------------------------------------------
class aged_associative_container_Tests :
public aged_associative_container_TestsBase
class aged_set_test : public aged_associative_container_test_base
{
public:
void runTest ()
// Compile time checks
typedef std::string Key;
typedef int T;
static_assert (std::is_same <
aged_set <Key>,
detail::aged_ordered_container <false, false, Key, void>>::value,
"bad alias: aged_set");
static_assert (std::is_same <
aged_multiset <Key>,
detail::aged_ordered_container <true, false, Key, void>>::value,
"bad alias: aged_multiset");
static_assert (std::is_same <
aged_map <Key, T>,
detail::aged_ordered_container <false, true, Key, T>>::value,
"bad alias: aged_map");
static_assert (std::is_same <
aged_multimap <Key, T>,
detail::aged_ordered_container <true, true, Key, T>>::value,
"bad alias: aged_multimap");
static_assert (std::is_same <
aged_unordered_set <Key>,
detail::aged_unordered_container <false, false, Key, void>>::value,
"bad alias: aged_unordered_set");
static_assert (std::is_same <
aged_unordered_multiset <Key>,
detail::aged_unordered_container <true, false, Key, void>>::value,
"bad alias: aged_unordered_multiset");
static_assert (std::is_same <
aged_unordered_map <Key, T>,
detail::aged_unordered_container <false, true, Key, T>>::value,
"bad alias: aged_unordered_map");
static_assert (std::is_same <
aged_unordered_multimap <Key, T>,
detail::aged_unordered_container <true, true, Key, T>>::value,
"bad alias: aged_unordered_multimap");
void run ()
{
checkAliases ();
testMaybeUnordered <false> ();
testMaybeUnordered <true> ();
testMaybeUnorderedMultiMap <false, false, false>();
}
};
static aged_associative_container_Tests aged_associative_container_tests;
class aged_map_test : public aged_associative_container_test_base
{
public:
void run ()
{
testMaybeUnorderedMultiMap <false, false, true>();
}
};
class aged_multiset_test : public aged_associative_container_test_base
{
public:
void run ()
{
testMaybeUnorderedMultiMap <false, true, false>();
}
};
class aged_multimap_test : public aged_associative_container_test_base
{
public:
void run ()
{
testMaybeUnorderedMultiMap <false, true, true>();
}
};
class aged_unordered_set_test : public aged_associative_container_test_base
{
public:
void run ()
{
testMaybeUnorderedMultiMap <true, false, false>();
}
};
class aged_unordered_map_test : public aged_associative_container_test_base
{
public:
void run ()
{
testMaybeUnorderedMultiMap <true, false, true>();
}
};
class aged_unordered_multiset_test : public aged_associative_container_test_base
{
public:
void run ()
{
testMaybeUnorderedMultiMap <true, true, false>();
}
};
class aged_unordered_multimap_test : public aged_associative_container_test_base
{
public:
void run ()
{
testMaybeUnorderedMultiMap <true, true, true>();
}
};
BEAST_DEFINE_TESTSUITE(aged_set,container,beast);
BEAST_DEFINE_TESTSUITE(aged_map,container,beast);
BEAST_DEFINE_TESTSUITE(aged_multiset,container,beast);
BEAST_DEFINE_TESTSUITE(aged_multimap,container,beast);
BEAST_DEFINE_TESTSUITE(aged_unordered_set,container,beast);
BEAST_DEFINE_TESTSUITE(aged_unordered_map,container,beast);
BEAST_DEFINE_TESTSUITE(aged_unordered_multiset,container,beast);
BEAST_DEFINE_TESTSUITE(aged_unordered_multimap,container,beast);
}

View File

@@ -17,14 +17,15 @@
*/
//==============================================================================
#include "../../../modules/beast_core/beast_core.h" // for UnitTest
#include "../../unit_test/suite.h"
#include "../buffer_view.h"
#include "../../cxx14/algorithm.h" // <algorithm>
namespace beast {
class buffer_view_Tests : public UnitTest
class buffer_view_test : public unit_test::suite
{
public:
// Returns `true` if the iterator distance matches the size
@@ -153,7 +154,7 @@ public:
// Test empty containers
void testEmpty()
{
beginTestCase ("empty");
testcase ("empty");
buffer_view <char> v1;
checkEmpty (v1);
@@ -239,11 +240,11 @@ public:
void testConstruct()
{
beginTestCase ("std::vector <char>");
testcase ("std::vector <char>");
testConstruct (
std::vector <char> ({'h', 'e', 'l', 'l', 'o'}));
beginTestCase ("std::string <char>");
testcase ("std::string <char>");
testConstruct (
std::basic_string <char> ("hello"));
}
@@ -252,7 +253,7 @@ public:
void testCoerce()
{
beginTestCase ("coerce");
testcase ("coerce");
std::string const s ("hello");
const_buffer_view <unsigned char> v (s);
@@ -264,7 +265,7 @@ public:
void testAssign()
{
beginTestCase ("testAssign");
testcase ("testAssign");
std::vector <int> v1({1, 2, 3});
buffer_view<int> r1(v1);
std::vector <int> v2({4, 5, 6, 7});
@@ -305,19 +306,15 @@ public:
static_assert (std::is_nothrow_move_assignable <
buffer_view <int>>::value, "");
void runTest()
void run()
{
testEmpty();
testConstruct();
testCoerce();
testAssign();
}
buffer_view_Tests() : UnitTest ("buffer_view", "beast")
{
}
};
static buffer_view_Tests buffer_view_tests;
BEAST_DEFINE_TESTSUITE(buffer_view,container,beast);
}

View File

@@ -21,9 +21,9 @@
#include "../../BeastConfig.h"
#endif
#include "../../modules/beast_core/beast_core.h" // for UnitTest
#include "impl/BinaryEncoding.cpp"
#include "impl/MurmurHash.cpp"
#include "impl/Sha256.cpp"
#include "impl/UnsignedInteger.cpp"
#include "tests/BinaryEncoding.test.cpp"
#include "tests/UnsignedInteger.test.cpp"

View File

@@ -23,6 +23,8 @@
#include "UnsignedIntegerCalc.h"
#include "MurmurHash.h"
#include "../../modules/beast_core/beast_core.h" // FIX ASAP
#include <cstdint>
#include <memory>

View File

@@ -20,6 +20,7 @@
#ifndef BEAST_CRYPTO_UNSIGNEDINTEGERCALC_H_INCLUDED
#define BEAST_CRYPTO_UNSIGNEDINTEGERCALC_H_INCLUDED
#include <cassert>
#include <cstdint>
namespace beast {
@@ -155,7 +156,7 @@ public:
*/
UnsignedIntegerCalc& operator= (UnsignedIntegerCalc const& other)
{
bassert (other.size() <= size());
assert (other.size() <= size());
size_type n (size());
UInt* dest (m_values + size());
for (; n-- > other.size();)
@@ -335,7 +336,7 @@ public:
}
*lhs++ = UInt (part);
}
bassert (carry == 0); // overflow
assert (carry == 0); // overflow
return *this;
}
@@ -359,7 +360,7 @@ public:
carry = part >> numBits;
*lhs = UInt (part & maxUInt);
}
bassert (carry == 0); // overflow
assert (carry == 0); // overflow
return *this;
}

View File

@@ -5,8 +5,7 @@
Portions are Copyright (c) 2013 the authors listed at the following URL,
and/or the authors of referenced articles or incorporated external code:
http://en.literateprograms.org/Arbitrary-precision_integer_arithmetic_(C)?action=history&offset=20100923155004
http://en.literateprograms.org/Arbitrary-precision_integer_arithmetic_(C)
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
@@ -23,6 +22,8 @@
#include "../UnsignedInteger.h"
#include "../../unit_test/suite.h"
namespace beast {
namespace multiprecsion {
@@ -31,7 +32,7 @@ namespace multiprecsion {
/* Copyright (c) 2013 the authors listed at the following URL, and/or
the authors of referenced articles or incorporated external code:
http://en.literateprograms.org/Arbitrary-precision_integer_arithmetic_(C)?action=history&offset=20100923155004
http://en.literateprograms.org/Arbitrary-precision_integer_arithmetic_(C)
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
@@ -342,63 +343,4 @@ char* integer_to_string(integer x) {
}
//------------------------------------------------------------------------------
class UnsignedIntegerTests : public UnitTest
{
public:
UnsignedIntegerTests () : UnitTest ("UnsignedInteger", "beast")
{
}
template <unsigned int Bytes>
void runTest ()
{
typedef UnsignedInteger <Bytes> UInt;
String s;
s << "Bytes=" << String(Bytes);
beginTestCase (s);
UInt zero;
zero.fill (0);
expect (zero.isZero (), "should be zero");
expect (! zero.isNotZero (), "sould not be non-zero");
UInt one (UInt::createFromInteger (1U));
expect (one == UInt::createFromInteger (1U), "should be equal");
expect (! one.isZero (), "should not be zero");
expect (one.isNotZero (), "sould be non-zero");
expect (zero < one, "should be less");
expect (one > zero, "should be greater");
expect (zero >= zero, "should be less than or equal");
expect (one <= one, "should be less than or equal");
expect (zero == zero, "should be equal");
expect (zero != one, "should not be equal");
expect (zero == UInt::createFromInteger (0U), "should be zero");
expect (one == UInt::createFromInteger (1U), "should be one");
expect (one != UInt::createFromInteger (2U), "should not be two");
UInt largest = UInt::createFilled (0xff);
expect (largest > zero && largest > one, "should be greater");
}
void runTest()
{
runTest <16> ();
runTest <33> ();
}
private:
};
static UnsignedIntegerTests unsignedIntegerTests;
}

View File

@@ -20,6 +20,8 @@
#include "../BinaryEncoding.h"
#include "../UnsignedInteger.h"
#include "../../unit_test/suite.h"
#include <cstddef>
#include <string>
@@ -276,19 +278,20 @@ public:
//------------------------------------------------------------------------------
class BinaryEncodingTests : public UnitTest
class BinaryEncoding_test : public unit_test::suite
{
public:
// This is a baseline for the other tests
template <std::size_t Bytes>
void testBase16 ()
{
beginTestCase ("base16");
Random r;
testcase ("base16");
for (int i = 0; i < 50; ++i)
{
typedef UnsignedInteger <Bytes> UInt;
UInt v0;
random().fillBitsRandomly (v0.begin(), UInt::size);
r.fillBitsRandomly (v0.begin(), UInt::size);
std::string const good (HexEncoding::encode (v0));
UInt v1;
@@ -299,8 +302,8 @@ public:
Base16Conversion c;
std::string const check (BinaryEncoding::encode (v0, c));
if (! expect (good == check))
logMessage (String ("expected ") + good + " but got " + check);
expect (good == check,
std::string ("expected ") + good + " but got " + check);
}
}
}
@@ -313,7 +316,8 @@ public:
typedef UnsignedInteger <Bytes> UInt;
UInt v1 (vin.c_str());
std::string const s1 (BinaryEncoding::encode (v1, c));
logMessage (vout + " to " + s1);
log <<
vout + " to " + s1;
expect (vout == s1);
UInt v2;
@@ -321,14 +325,14 @@ public:
if (expect (success))
{
std::string const s2 (BinaryEncoding::encode (v2, c));
logMessage (vin + " to " + s2);
//expect (vin == v2);
log <<
vin + " to " + s2;
}
}
void testBase64 ()
{
beginTestCase ("Base64");
testcase ("Base64");
// input (uint)
std::string const vin [] = {
@@ -354,12 +358,16 @@ public:
{
typedef UnsignedInteger <Bytes> UInt;
beginTestCase (String (c.name()) + " <" + String::fromNumber (Bytes) + ">");
std::stringstream ss;
ss <<
c.name() << " <" << Bytes << ">";
testcase (ss.str());
Random r;
for (int i = 0; i < 50; ++i)
{
UInt v1;
random().fillBitsRandomly (v1.begin(), UInt::size);
r.fillBitsRandomly (v1.begin(), UInt::size);
std::string const s1 (BinaryEncoding::encode (v1, c));
UInt v2;
@@ -369,7 +377,7 @@ public:
}
}
void runTest ()
void run ()
{
testBase16 <10> ();
@@ -394,12 +402,8 @@ public:
testEncode <BitcoinBase58Conversion, 33> ();
#endif
}
BinaryEncodingTests () : UnitTest ("BinaryEncoding", "beast", runManual)
{
}
};
static BinaryEncodingTests BinaryEncodingTests;
BEAST_DEFINE_TESTSUITE_MANUAL(BinaryEncoding,crypto,beast);
}

View File

@@ -0,0 +1,81 @@
//------------------------------------------------------------------------------
/*
This file is part of Beast: https://github.com/vinniefalco/Beast
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
Portions are Copyright (c) 2013 the authors listed at the following URL,
and/or the authors of referenced articles or incorporated external code:
http://en.literateprograms.org/Arbitrary-precision_integer_arithmetic_(C)
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
//==============================================================================
#include "../UnsignedInteger.h"
#include "../../unit_test/suite.h"
namespace beast {
class UnsignedInteger_test : public unit_test::suite
{
public:
template <unsigned int Bytes>
void test ()
{
typedef UnsignedInteger <Bytes> UInt;
std::stringstream ss;
ss <<
"bytes=" << Bytes;
testcase (ss.str());
UInt zero;
zero.fill (0);
expect (zero.isZero (), "should be zero");
expect (! zero.isNotZero (), "sould not be non-zero");
UInt one (UInt::createFromInteger (1U));
expect (one == UInt::createFromInteger (1U), "should be equal");
expect (! one.isZero (), "should not be zero");
expect (one.isNotZero (), "sould be non-zero");
expect (zero < one, "should be less");
expect (one > zero, "should be greater");
expect (zero >= zero, "should be less than or equal");
expect (one <= one, "should be less than or equal");
expect (zero == zero, "should be equal");
expect (zero != one, "should not be equal");
expect (zero == UInt::createFromInteger (0U), "should be zero");
expect (one == UInt::createFromInteger (1U), "should be one");
expect (one != UInt::createFromInteger (2U), "should not be two");
UInt largest = UInt::createFilled (0xff);
expect (largest > zero && largest > one, "should be greater");
}
void run()
{
test <16> ();
test <33> ();
}
private:
};
BEAST_DEFINE_TESTSUITE(UnsignedInteger,crypto,beast);
}

View File

@@ -23,12 +23,12 @@
#include "../utility.h"
#include "../../../modules/beast_core/beast_core.h" // for UnitTest
#include "../../unit_test/suite.h"
namespace beast {
namespace asio {
class integer_sequence_Tests : public UnitTest
class integer_sequence_test : public unit_test::suite
{
public:
template <class AtContainer, class T, T... I>
@@ -41,10 +41,8 @@ public:
return std::make_tuple (std::get <I> (t)...);
}
void runTest()
void run()
{
beginTestCase ("call");
// Code from
// http://llvm.org/svn/llvm-project/libcxx/trunk/test/utilities/intseq/intseq.general/integer_seq.pass.cpp
@@ -103,13 +101,9 @@ public:
expect ( tsizemix == std::make_tuple ( 11, 11, 12, 13, 15 ));
pass();
}
integer_sequence_Tests() : UnitTest ("integer_sequence", "beast")
{
}
};
static integer_sequence_Tests integer_sequence_tests;
BEAST_DEFINE_TESTSUITE(integer_sequence,cxx14,beast);
}
}

View File

@@ -25,3 +25,5 @@
#include "impl/ParsedURL.cpp"
#include "impl/joyent_parser.cpp"
#include "impl/raw_parser.cpp"
#include "tests/ParsedURL.test.cpp"

View File

@@ -18,11 +18,12 @@
//==============================================================================
#include "../ParsedURL.h"
#include "../../../modules/beast_core/beast_core.h" // for UnitTest
#include "../../strings/String.h"
#include "joyent_parser.h"
#include <cstdint>
namespace beast {
ParsedURL::ParsedURL ()
@@ -146,35 +147,4 @@ URL ParsedURL::url () const
return m_url;
}
//------------------------------------------------------------------------------
class ParsedURLTests : public UnitTest
{
public:
void checkURL (String const& url)
{
ParsedURL result (url);
expect (result.error () == 0);
expect (result.url ().toString () == url);
}
void testURL ()
{
beginTestCase ("parse URL");
checkURL ("http://www.boost.org/doc/libs/1_54_0/doc/html/boost_asio/reference.html");
}
void runTest ()
{
testURL ();
}
ParsedURLTests () : UnitTest ("ParsedURL", "beast", runManual)
{
}
};
static ParsedURLTests parsedURLTests;
}

View File

@@ -0,0 +1,51 @@
//------------------------------------------------------------------------------
/*
This file is part of Beast: https://github.com/vinniefalco/Beast
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
//==============================================================================
#include "../ParsedURL.h"
#include "../../unit_test/suite.h"
#include "../impl/joyent_parser.h"
namespace beast {
class ParsedURL_test : public unit_test::suite
{
public:
void checkURL (String const& url)
{
ParsedURL result (url);
expect (result.error () == 0);
expect (result.url ().toString () == url);
}
void testURL ()
{
checkURL ("http://www.boost.org/doc/libs/1_54_0/doc/html/boost_asio/reference.html");
}
void run ()
{
testURL ();
}
};
BEAST_DEFINE_TESTSUITE(ParsedURL,http,beast);
}

View File

@@ -20,6 +20,9 @@
#ifndef BEAST_INSIGHT_BASEIMPL_H_INCLUDED
#define BEAST_INSIGHT_BASEIMPL_H_INCLUDED
#include <chrono>
#include <cstdint>
#include <functional>
#include <memory>
namespace beast {

View File

@@ -20,14 +20,14 @@
#ifndef BEAST_INSIGHT_COLLECTOR_H_INCLUDED
#define BEAST_INSIGHT_COLLECTOR_H_INCLUDED
#include <string>
#include "Counter.h"
#include "Event.h"
#include "Gauge.h"
#include "Hook.h"
#include "Meter.h"
#include <string>
namespace beast {
namespace insight {

View File

@@ -20,11 +20,11 @@
#ifndef BEAST_INSIGHT_COUNTER_H_INCLUDED
#define BEAST_INSIGHT_COUNTER_H_INCLUDED
#include <memory>
#include "Base.h"
#include "CounterImpl.h"
#include <memory>
namespace beast {
namespace insight {
@@ -60,32 +60,58 @@ public:
/** Increment the counter. */
/** @{ */
void increment (value_type amount) const
void
increment (value_type amount) const
{
if (m_impl)
m_impl->increment (amount);
}
Counter const& operator+= (value_type amount) const
{ increment (amount); return *this; }
Counter const&
operator+= (value_type amount) const
{
increment (amount);
return *this;
}
Counter const& operator-= (value_type amount) const
{ increment (-amount); return *this; }
Counter const&
operator-= (value_type amount) const
{
increment (-amount);
return *this;
}
Counter const& operator++ () const
{ increment (1); return *this; }
Counter const&
operator++ () const
{
increment (1);
return *this;
}
Counter const& operator++ (int) const
{ increment (1); return *this; }
Counter const&
operator++ (int) const
{
increment (1);
return *this;
}
Counter const& operator-- () const
{ increment (-1); return *this; }
Counter const&
operator-- () const
{
increment (-1);
return *this;
}
Counter const& operator-- (int) const
{ increment (-1); return *this; }
Counter const&
operator-- (int) const
{
increment (-1);
return *this;
}
/** @} */
std::shared_ptr <CounterImpl> const& impl () const
std::shared_ptr <CounterImpl> const&
impl () const
{
return m_impl;
}

View File

@@ -20,8 +20,6 @@
#ifndef BEAST_INSIGHT_COUNTERIMPL_H_INCLUDED
#define BEAST_INSIGHT_COUNTERIMPL_H_INCLUDED
#include <memory>
#include "BaseImpl.h"
namespace beast {
@@ -34,7 +32,7 @@ class CounterImpl
, public BaseImpl
{
public:
typedef int64 value_type;
typedef std::int64_t value_type;
virtual ~CounterImpl () = 0;
virtual void increment (value_type amount) = 0;

View File

@@ -20,14 +20,14 @@
#ifndef BEAST_INSIGHT_EVENT_H_INCLUDED
#define BEAST_INSIGHT_EVENT_H_INCLUDED
#include <chrono>
#include <memory>
#include "Base.h"
#include "EventImpl.h"
#include "../chrono/chrono_util.h"
#include <chrono>
#include <memory>
namespace beast {
namespace insight {
@@ -62,7 +62,8 @@ public:
/** Push an event notification. */
template <class Rep, class Period>
void notify (std::chrono::duration <Rep, Period> const& value) const
void
notify (std::chrono::duration <Rep, Period> const& value) const
{
if (m_impl)
m_impl->notify (ceil <value_type> (value));

View File

@@ -20,8 +20,6 @@
#ifndef BEAST_INSIGHT_EVENTIMPL_H_INCLUDED
#define BEAST_INSIGHT_EVENTIMPL_H_INCLUDED
#include <memory>
#include "BaseImpl.h"
namespace beast {

View File

@@ -20,11 +20,11 @@
#ifndef BEAST_INSIGHT_GAUGE_H_INCLUDED
#define BEAST_INSIGHT_GAUGE_H_INCLUDED
#include <memory>
#include "Base.h"
#include "GaugeImpl.h"
#include <memory>
namespace beast {
namespace insight {
@@ -84,26 +84,51 @@ public:
m_impl->increment (amount);
}
Gauge const& operator+= (difference_type amount) const
{ increment (amount); return *this; }
Gauge const&
operator+= (difference_type amount) const
{
increment (amount);
return *this;
}
Gauge const& operator-= (difference_type amount) const
{ increment (-amount); return *this; }
Gauge const&
operator-= (difference_type amount) const
{
increment (-amount);
return *this;
}
Gauge const& operator++ () const
{ increment (1); return *this; }
Gauge const&
operator++ () const
{
increment (1);
return *this;
}
Gauge const& operator++ (int) const
{ increment (1); return *this; }
Gauge const&
operator++ (int) const
{
increment (1);
return *this;
}
Gauge const& operator-- () const
{ increment (-1); return *this; }
Gauge const&
operator-- () const
{
increment (-1);
return *this;
}
Gauge const& operator-- (int) const
{ increment (-1); return *this; }
Gauge const&
operator-- (int) const
{
increment (-1);
return *this;
}
/** @} */
std::shared_ptr <GaugeImpl> const& impl () const
std::shared_ptr <GaugeImpl> const&
impl () const
{
return m_impl;
}

View File

@@ -20,8 +20,6 @@
#ifndef BEAST_INSIGHT_GAUGEIMPL_H_INCLUDED
#define BEAST_INSIGHT_GAUGEIMPL_H_INCLUDED
#include <memory>
#include "BaseImpl.h"
namespace beast {
@@ -34,8 +32,8 @@ class GaugeImpl
, public BaseImpl
{
public:
typedef uint64 value_type;
typedef int64 difference_type;
typedef std::uint64_t value_type;
typedef std::int64_t difference_type;
virtual ~GaugeImpl () = 0;
virtual void set (value_type value) = 0;

View File

@@ -20,10 +20,11 @@
#ifndef BEAST_INSIGHT_GROUP_H_INCLUDED
#define BEAST_INSIGHT_GROUP_H_INCLUDED
#include <memory>
#include "Collector.h"
#include <memory>
#include <string>
namespace beast {
namespace insight {

View File

@@ -20,12 +20,12 @@
#ifndef BEAST_INSIGHT_GROUPS_H_INCLUDED
#define BEAST_INSIGHT_GROUPS_H_INCLUDED
#include <memory>
#include <string>
#include "Collector.h"
#include "Group.h"
#include <memory>
#include <string>
namespace beast {
namespace insight {
@@ -37,9 +37,12 @@ public:
/** Find or create a new collector with a given name. */
/** @{ */
virtual Group::ptr const& get (std::string const& name) = 0;
virtual
Group::ptr const&
get (std::string const& name) = 0;
Group::ptr const& operator[] (std::string const& name)
Group::ptr const&
operator[] (std::string const& name)
{
return get (name);
}

View File

@@ -20,11 +20,11 @@
#ifndef BEAST_INSIGHT_HOOK_H_INCLUDED
#define BEAST_INSIGHT_HOOK_H_INCLUDED
#include <memory>
#include "Base.h"
#include "HookImpl.h"
#include <memory>
namespace beast {
namespace insight {

View File

@@ -20,9 +20,6 @@
#ifndef BEAST_INSIGHT_HOOKIMPL_H_INCLUDED
#define BEAST_INSIGHT_HOOKIMPL_H_INCLUDED
#include <functional>
#include <memory>
#include "BaseImpl.h"
namespace beast {

View File

@@ -23,8 +23,6 @@
#include "../Config.h"
#include "../../modules/beast_core/beast_core.h" // for UnitTest
#include "../Insight.h"
#include "impl/Collector.cpp"

View File

@@ -20,8 +20,6 @@
#ifndef BEAST_INSIGHT_METERIMPL_H_INCLUDED
#define BEAST_INSIGHT_METERIMPL_H_INCLUDED
#include <memory>
#include "BaseImpl.h"
namespace beast {
@@ -34,7 +32,7 @@ class MeterImpl
, public BaseImpl
{
public:
typedef uint64 value_type;
typedef std::uint64_t value_type;
virtual ~MeterImpl () = 0;
virtual void increment (value_type amount) = 0;

View File

@@ -22,6 +22,7 @@
#include "Collector.h"
#include "../utility/Journal.h"
#include "../net/IPEndpoint.h"
namespace beast {
@@ -39,7 +40,9 @@ public:
@param prefix A string pre-pended before each metric name.
@param journal Destination for logging output.
*/
static std::shared_ptr <StatsDCollector> New (IP::Endpoint const& address,
static
std::shared_ptr <StatsDCollector>
New (IP::Endpoint const& address,
std::string const& prefix, Journal journal);
};

View File

@@ -18,19 +18,21 @@
//==============================================================================
#include "../../asio/IPAddressConversion.h"
#include "../../intrusive/List.h"
#include "../../threads/SharedData.h"
#include <deque>
#include <climits>
#include <set>
#include <sstream>
#include <thread>
#include <boost/asio.hpp>
#include <boost/asio/ip/tcp.hpp>
#include <boost/bind.hpp>
#include <boost/move/move.hpp>
#include <boost/optional.hpp>
#include <cassert>
#include <climits>
#include <deque>
#include <set>
#include <sstream>
#include <thread>
#ifndef BEAST_STATSDCOLLECTOR_TRACING_ENABLED
#define BEAST_STATSDCOLLECTOR_TRACING_ENABLED 0
#endif
@@ -364,7 +366,7 @@ public:
{
std::string const& buffer (*iter);
std::size_t const length (buffer.size ());
check_precondition (! buffer.empty ());
assert (! buffer.empty ());
if (! buffers.empty () && (size + length) > max_packet_size)
{
#if BEAST_STATSDCOLLECTOR_TRACING_ENABLED

View File

@@ -17,18 +17,11 @@
*/
//==============================================================================
#if BEAST_INCLUDE_BEASTCONFIG
#include "../../BeastConfig.h"
#endif
#include "../Config.h"
#include "../../modules/beast_core/beast_core.h" // for UnitTest
#include "impl/DynamicBuffer.cpp"
#include "impl/IPAddress.cpp"
#include "impl/IPAddressV4.cpp"
#include "impl/IPAddressV6.cpp"
#include "impl/IPEndpoint.cpp"
#include "tests/IPEndpoint.test.cpp"

View File

@@ -17,10 +17,15 @@
*/
//==============================================================================
#include <memory>
#if BEAST_INCLUDE_BEASTCONFIG
#include "../../BeastConfig.h"
#endif
#include "../DynamicBuffer.h"
#include <algorithm>
#include <memory>
namespace beast {
DynamicBuffer::DynamicBuffer (size_type blocksize)

View File

@@ -17,7 +17,14 @@
*/
//==============================================================================
#if BEAST_INCLUDE_BEASTCONFIG
#include "../../BeastConfig.h"
#endif
#include "../IPAddressV4.h"
#include "../detail/Parse.h"
#include <sstream>
namespace beast {
namespace IP {

View File

@@ -17,6 +17,10 @@
*/
//==============================================================================
#if BEAST_INCLUDE_BEASTCONFIG
#include "../../BeastConfig.h"
#endif
#include "../IPAddressV6.h"
namespace beast {

View File

@@ -17,6 +17,11 @@
*/
//==============================================================================
#if BEAST_INCLUDE_BEASTCONFIG
#include "../../BeastConfig.h"
#endif
#include "../IPEndpoint.h"
#include "../detail/Parse.h"
namespace beast {

View File

@@ -17,17 +17,23 @@
*/
//==============================================================================
#include <typeinfo>
#if BEAST_INCLUDE_BEASTCONFIG
#include "../../BeastConfig.h"
#endif
#include "../IPEndpoint.h"
#include "../detail/Parse.h"
#include "../../unit_test/suite.h"
#include <typeinfo>
namespace beast {
namespace IP {
//------------------------------------------------------------------------------
class IPAddressTests : public UnitTest
class IPEndpoint_test : public unit_test::suite
{
public:
void shouldParseV4 (std::string const& s, uint32 value)
@@ -51,7 +57,7 @@ public:
void testAddressV4 ()
{
beginTestCase ("AddressV4");
testcase ("AddressV4");
expect (AddressV4().value == 0);
expect (is_unspecified (AddressV4()));
@@ -100,7 +106,7 @@ public:
void testAddressV4Proxy ()
{
beginTestCase ("AddressV4::Proxy");
testcase ("AddressV4::Proxy");
AddressV4 v4 (10, 0, 0, 1);
expect (v4[0]==10);
@@ -122,7 +128,7 @@ public:
void testAddress ()
{
beginTestCase ("Address");
testcase ("Address");
std::pair <Address, bool> result (
Address::from_string ("1.2.3.4"));
@@ -135,7 +141,7 @@ public:
void testEndpoint ()
{
beginTestCase ("Endpoint");
testcase ("Endpoint");
{
std::pair <Endpoint, bool> result (
@@ -220,7 +226,7 @@ public:
template <typename T>
void testParse (char const* name)
{
beginTestCase (name);
testcase (name);
shouldPass <T> ("0.0.0.0");
shouldPass <T> ("192.168.0.1");
@@ -235,7 +241,7 @@ public:
shouldFail <T> ("1.2.3:80");
}
void runTest ()
void run ()
{
testAddressV4 ();
testAddressV4Proxy();
@@ -244,13 +250,9 @@ public:
testParse <Endpoint> ("Parse Endpoint");
}
IPAddressTests () : UnitTest ("IP::Endpoint", "beast")
{
}
};
static IPAddressTests ipEndpointTests;
BEAST_DEFINE_TESTSUITE(IPEndpoint,net,beast);
}
}

View File

@@ -21,6 +21,7 @@
#define BEAST_STREAMS_BASIC_SCOPED_OSTREAM_H_INCLUDED
#include "../cxx14/memory.h" // <memory>
#include <functional>
#include <memory>
#include <sstream>

View File

@@ -17,54 +17,4 @@
*/
//==============================================================================
#if BEAST_INCLUDE_BEASTCONFIG
#include "../../BeastConfig.h"
#endif
#include "../../modules/beast_core/beast_core.h"
#include "basic_abstract_ostream.h"
namespace beast {
class streams_Tests : public UnitTest
{
public:
class test_stream : public basic_abstract_ostream <char>
{
public:
explicit test_stream (UnitTest& test)
: m_test (test)
{
}
void write (string_type const& s) override
{
m_test.logMessage (s);
}
test_stream& operator= (test_stream const&) = delete;
private:
UnitTest& m_test;
};
void runTest()
{
beginTestCase ("stream");
test_stream ts (*this);
ts << "Hello";
pass();
}
streams_Tests() : UnitTest ("streams", "beast")
{
}
};
static streams_Tests streams_tests;
}
#include "tests/basic_abstract_ostream.test.cpp"

View File

@@ -0,0 +1,66 @@
//------------------------------------------------------------------------------
/*
This file is part of Beast: https://github.com/vinniefalco/Beast
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
//==============================================================================
#if BEAST_INCLUDE_BEASTCONFIG
#include "../../BeastConfig.h"
#endif
#include "../basic_abstract_ostream.h"
#include "../../unit_test/suite.h"
namespace beast {
class basic_abstract_ostream_test : public unit_test::suite
{
public:
class test_stream : public basic_abstract_ostream <char>
{
public:
test_stream&
operator= (test_stream const&) = delete;
explicit
test_stream (unit_test::suite& suite_)
: m_suite (suite_)
{
}
void write (string_type const& s) override
{
m_suite.log << s;
}
private:
unit_test::suite& m_suite;
};
void run()
{
test_stream ts (*this);
ts << "Hello";
pass();
}
};
BEAST_DEFINE_TESTSUITE(basic_abstract_ostream,streams,beast);
}

View File

@@ -17,9 +17,5 @@
*/
//==============================================================================
#if BEAST_INCLUDE_BEASTCONFIG
#include "../../BeastConfig.h"
#endif
#include "impl/CharacterFunctions.cpp"
#include "impl/String.cpp"

View File

@@ -21,6 +21,10 @@
*/
//==============================================================================
#if BEAST_INCLUDE_BEASTCONFIG
#include "../../BeastConfig.h"
#endif
#include "../CharacterFunctions.h"
#include <cctype>

View File

@@ -21,7 +21,9 @@
*/
//==============================================================================
#include <stdarg.h>
#if BEAST_INCLUDE_BEASTCONFIG
#include "../../BeastConfig.h"
#endif
#include "../String.h"
#include "../NewLine.h"
@@ -32,7 +34,7 @@
#include "../../Arithmetic.h"
#include "../../HeapBlock.h"
#include "../../../modules/beast_core/beast_core.h" // for UnitTest
#include <stdarg.h>
namespace beast {
@@ -1976,364 +1978,4 @@ String String::fromUTF8 (const char* const buffer, int bufferSizeBytes)
#pragma warning (pop)
#endif
//==============================================================================
//==============================================================================
#ifdef BEAST_UNITTEST_H_INCLUDED
class StringTests : public UnitTest
{
public:
StringTests() : UnitTest ("String", "beast")
{
}
template <class CharPointerType>
struct TestUTFConversion
{
static void test (UnitTest& test)
{
String s (createRandomWideCharString());
typename CharPointerType::CharType buffer [300];
memset (buffer, 0xff, sizeof (buffer));
CharPointerType (buffer).writeAll (s.toUTF32());
test.expectEquals (String (CharPointerType (buffer)), s);
memset (buffer, 0xff, sizeof (buffer));
CharPointerType (buffer).writeAll (s.toUTF16());
test.expectEquals (String (CharPointerType (buffer)), s);
memset (buffer, 0xff, sizeof (buffer));
CharPointerType (buffer).writeAll (s.toUTF8());
test.expectEquals (String (CharPointerType (buffer)), s);
test.expect (CharPointerType::isValidString (buffer, (int) strlen ((const char*) buffer)));
}
};
static String createRandomWideCharString()
{
beast_wchar buffer[50] = { 0 };
Random r;
for (int i = 0; i < numElementsInArray (buffer) - 1; ++i)
{
if (r.nextBool())
{
do
{
buffer[i] = (beast_wchar) (1 + r.nextInt (0x10ffff - 1));
}
while (! CharPointer_UTF16::canRepresent (buffer[i]));
}
else
buffer[i] = (beast_wchar) (1 + r.nextInt (0xff));
}
return CharPointer_UTF32 (buffer);
}
void runTest()
{
{
beginTestCase ("Basics");
expect (String().length() == 0);
expect (String() == String::empty);
String s1, s2 ("abcd");
expect (s1.isEmpty() && ! s1.isNotEmpty());
expect (s2.isNotEmpty() && ! s2.isEmpty());
expect (s2.length() == 4);
s1 = "abcd";
expect (s2 == s1 && s1 == s2);
expect (s1 == "abcd" && s1 == L"abcd");
expect (String ("abcd") == String (L"abcd"));
expect (String ("abcdefg", 4) == L"abcd");
expect (String ("abcdefg", 4) == String (L"abcdefg", 4));
expect (String::charToString ('x') == "x");
expect (String::charToString (0) == String::empty);
expect (s2 + "e" == "abcde" && s2 + 'e' == "abcde");
expect (s2 + L'e' == "abcde" && s2 + L"e" == "abcde");
expect (s1.equalsIgnoreCase ("abcD") && s1 < "abce" && s1 > "abbb");
expect (s1.startsWith ("ab") && s1.startsWith ("abcd") && ! s1.startsWith ("abcde"));
expect (s1.startsWithIgnoreCase ("aB") && s1.endsWithIgnoreCase ("CD"));
expect (s1.endsWith ("bcd") && ! s1.endsWith ("aabcd"));
expectEquals (s1.indexOf (String::empty), 0);
expectEquals (s1.indexOfIgnoreCase (String::empty), 0);
expect (s1.startsWith (String::empty) && s1.endsWith (String::empty) && s1.contains (String::empty));
expect (s1.contains ("cd") && s1.contains ("ab") && s1.contains ("abcd"));
expect (s1.containsChar ('a'));
expect (! s1.containsChar ('x'));
expect (! s1.containsChar (0));
expect (String ("abc foo bar").containsWholeWord ("abc") && String ("abc foo bar").containsWholeWord ("abc"));
}
{
beginTestCase ("Operations");
String s ("012345678");
expect (s.hashCode() != 0);
expect (s.hashCode64() != 0);
expect (s.hashCode() != (s + s).hashCode());
expect (s.hashCode64() != (s + s).hashCode64());
expect (s.compare (String ("012345678")) == 0);
expect (s.compare (String ("012345679")) < 0);
expect (s.compare (String ("012345676")) > 0);
expect (s.substring (2, 3) == String::charToString (s[2]));
expect (s.substring (0, 1) == String::charToString (s[0]));
expect (s.getLastCharacter() == s [s.length() - 1]);
expect (String::charToString (s.getLastCharacter()) == s.getLastCharacters (1));
expect (s.substring (0, 3) == L"012");
expect (s.substring (0, 100) == s);
expect (s.substring (-1, 100) == s);
expect (s.substring (3) == "345678");
expect (s.indexOf (L"45") == 4);
expect (String ("444445").indexOf ("45") == 4);
expect (String ("444445").lastIndexOfChar ('4') == 4);
expect (String ("45454545x").lastIndexOf (L"45") == 6);
expect (String ("45454545x").lastIndexOfAnyOf ("456") == 7);
expect (String ("45454545x").lastIndexOfAnyOf (L"456x") == 8);
expect (String ("abABaBaBa").lastIndexOfIgnoreCase ("aB") == 6);
expect (s.indexOfChar (L'4') == 4);
expect (s + s == "012345678012345678");
expect (s.startsWith (s));
expect (s.startsWith (s.substring (0, 4)));
expect (s.startsWith (s.dropLastCharacters (4)));
expect (s.endsWith (s.substring (5)));
expect (s.endsWith (s));
expect (s.contains (s.substring (3, 6)));
expect (s.contains (s.substring (3)));
expect (s.startsWithChar (s[0]));
expect (s.endsWithChar (s.getLastCharacter()));
expect (s [s.length()] == 0);
expect (String ("abcdEFGH").toLowerCase() == String ("abcdefgh"));
expect (String ("abcdEFGH").toUpperCase() == String ("ABCDEFGH"));
String s2 ("123");
s2 << ((int) 4) << ((short) 5) << "678" << L"9" << '0';
s2 += "xyz";
expect (s2 == "1234567890xyz");
beginTestCase ("Numeric conversions");
expect (String::empty.getIntValue() == 0);
expect (String::empty.getDoubleValue() == 0.0);
expect (String::empty.getFloatValue() == 0.0f);
expect (s.getIntValue() == 12345678);
expect (s.getLargeIntValue() == (int64) 12345678);
expect (s.getDoubleValue() == 12345678.0);
expect (s.getFloatValue() == 12345678.0f);
expect (String (-1234).getIntValue() == -1234);
expect (String ((int64) -1234).getLargeIntValue() == -1234);
expect (String (-1234.56).getDoubleValue() == -1234.56);
expect (String (-1234.56f).getFloatValue() == -1234.56f);
expect (String (std::numeric_limits<int>::max()).getIntValue() == std::numeric_limits<int>::max());
expect (String (std::numeric_limits<int>::min()).getIntValue() == std::numeric_limits<int>::min());
expect (String (std::numeric_limits<int64>::max()).getLargeIntValue() == std::numeric_limits<int64>::max());
expect (String (std::numeric_limits<int64>::min()).getLargeIntValue() == std::numeric_limits<int64>::min());
expect (("xyz" + s).getTrailingIntValue() == s.getIntValue());
expect (s.getHexValue32() == 0x12345678);
expect (s.getHexValue64() == (int64) 0x12345678);
expect (String::toHexString (0x1234abcd).equalsIgnoreCase ("1234abcd"));
expect (String::toHexString ((int64) 0x1234abcd).equalsIgnoreCase ("1234abcd"));
expect (String::toHexString ((short) 0x12ab).equalsIgnoreCase ("12ab"));
expectEquals (String (int (0)), "0");
expectEquals (String (short (0)), "0");
expectEquals (String (int64 (0)), "0");
expectEquals (String ((unsigned int) 0), "0");
expectEquals (String ((unsigned short) 0), "0");
expectEquals (String (uint64 (0)), "0");
expectEquals (String (int (-1)), "-1");
expectEquals (String (short (-1)), "-1");
expectEquals (String (int64 (-1)), "-1");
expectEquals (String (int (1)), "1");
expectEquals (String (short (1)), "1");
expectEquals (String (int64 (1)), "1");
expectEquals (String ((unsigned int) 1), "1");
expectEquals (String ((unsigned short) 1), "1");
expectEquals (String (uint64 (1)), "1");
unsigned char data[] = { 1, 2, 3, 4, 0xa, 0xb, 0xc, 0xd };
expect (String::toHexString (data, 8, 0).equalsIgnoreCase ("010203040a0b0c0d"));
expect (String::toHexString (data, 8, 1).equalsIgnoreCase ("01 02 03 04 0a 0b 0c 0d"));
expect (String::toHexString (data, 8, 2).equalsIgnoreCase ("0102 0304 0a0b 0c0d"));
beginTestCase ("Subsections");
String s3;
s3 = "abcdeFGHIJ";
expect (s3.equalsIgnoreCase ("ABCdeFGhiJ"));
expect (s3.compareIgnoreCase (L"ABCdeFGhiJ") == 0);
expect (s3.containsIgnoreCase (s3.substring (3)));
expect (s3.indexOfAnyOf ("xyzf", 2, true) == 5);
expect (s3.indexOfAnyOf (L"xyzf", 2, false) == -1);
expect (s3.indexOfAnyOf ("xyzF", 2, false) == 5);
expect (s3.containsAnyOf (L"zzzFs"));
expect (s3.startsWith ("abcd"));
expect (s3.startsWithIgnoreCase (L"abCD"));
expect (s3.startsWith (String::empty));
expect (s3.startsWithChar ('a'));
expect (s3.endsWith (String ("HIJ")));
expect (s3.endsWithIgnoreCase (L"Hij"));
expect (s3.endsWith (String::empty));
expect (s3.endsWithChar (L'J'));
expect (s3.indexOf ("HIJ") == 7);
expect (s3.indexOf (L"HIJK") == -1);
expect (s3.indexOfIgnoreCase ("hij") == 7);
expect (s3.indexOfIgnoreCase (L"hijk") == -1);
expect (s3.toStdString() == s3.toRawUTF8());
String s4 (s3);
s4.append (String ("xyz123"), 3);
expect (s4 == s3 + "xyz");
expect (String (1234) < String (1235));
expect (String (1235) > String (1234));
expect (String (1234) >= String (1234));
expect (String (1234) <= String (1234));
expect (String (1235) >= String (1234));
expect (String (1234) <= String (1235));
String s5 ("word word2 word3");
expect (s5.containsWholeWord (String ("word2")));
expect (s5.indexOfWholeWord ("word2") == 5);
expect (s5.containsWholeWord (L"word"));
expect (s5.containsWholeWord ("word3"));
expect (s5.containsWholeWord (s5));
expect (s5.containsWholeWordIgnoreCase (L"Word2"));
expect (s5.indexOfWholeWordIgnoreCase ("Word2") == 5);
expect (s5.containsWholeWordIgnoreCase (L"Word"));
expect (s5.containsWholeWordIgnoreCase ("Word3"));
expect (! s5.containsWholeWordIgnoreCase (L"Wordx"));
expect (! s5.containsWholeWordIgnoreCase ("xWord2"));
expect (s5.containsNonWhitespaceChars());
expect (s5.containsOnly ("ordw23 "));
expect (! String (" \n\r\t").containsNonWhitespaceChars());
expect (s5.matchesWildcard (L"wor*", false));
expect (s5.matchesWildcard ("wOr*", true));
expect (s5.matchesWildcard (L"*word3", true));
expect (s5.matchesWildcard ("*word?", true));
expect (s5.matchesWildcard (L"Word*3", true));
expect (! s5.matchesWildcard (L"*34", true));
expect (String ("xx**y").matchesWildcard ("*y", true));
expect (String ("xx**y").matchesWildcard ("x*y", true));
expect (String ("xx**y").matchesWildcard ("xx*y", true));
expect (String ("xx**y").matchesWildcard ("xx*", true));
expect (String ("xx?y").matchesWildcard ("x??y", true));
expect (String ("xx?y").matchesWildcard ("xx?y", true));
expect (! String ("xx?y").matchesWildcard ("xx?y?", true));
expect (String ("xx?y").matchesWildcard ("xx??", true));
expectEquals (s5.fromFirstOccurrenceOf (String::empty, true, false), s5);
expectEquals (s5.fromFirstOccurrenceOf ("xword2", true, false), s5.substring (100));
expectEquals (s5.fromFirstOccurrenceOf (L"word2", true, false), s5.substring (5));
expectEquals (s5.fromFirstOccurrenceOf ("Word2", true, true), s5.substring (5));
expectEquals (s5.fromFirstOccurrenceOf ("word2", false, false), s5.getLastCharacters (6));
expectEquals (s5.fromFirstOccurrenceOf (L"Word2", false, true), s5.getLastCharacters (6));
expectEquals (s5.fromLastOccurrenceOf (String::empty, true, false), s5);
expectEquals (s5.fromLastOccurrenceOf (L"wordx", true, false), s5);
expectEquals (s5.fromLastOccurrenceOf ("word", true, false), s5.getLastCharacters (5));
expectEquals (s5.fromLastOccurrenceOf (L"worD", true, true), s5.getLastCharacters (5));
expectEquals (s5.fromLastOccurrenceOf ("word", false, false), s5.getLastCharacters (1));
expectEquals (s5.fromLastOccurrenceOf (L"worD", false, true), s5.getLastCharacters (1));
expect (s5.upToFirstOccurrenceOf (String::empty, true, false).isEmpty());
expectEquals (s5.upToFirstOccurrenceOf ("word4", true, false), s5);
expectEquals (s5.upToFirstOccurrenceOf (L"word2", true, false), s5.substring (0, 10));
expectEquals (s5.upToFirstOccurrenceOf ("Word2", true, true), s5.substring (0, 10));
expectEquals (s5.upToFirstOccurrenceOf (L"word2", false, false), s5.substring (0, 5));
expectEquals (s5.upToFirstOccurrenceOf ("Word2", false, true), s5.substring (0, 5));
expectEquals (s5.upToLastOccurrenceOf (String::empty, true, false), s5);
expectEquals (s5.upToLastOccurrenceOf ("zword", true, false), s5);
expectEquals (s5.upToLastOccurrenceOf ("word", true, false), s5.dropLastCharacters (1));
expectEquals (s5.dropLastCharacters(1).upToLastOccurrenceOf ("word", true, false), s5.dropLastCharacters (1));
expectEquals (s5.upToLastOccurrenceOf ("Word", true, true), s5.dropLastCharacters (1));
expectEquals (s5.upToLastOccurrenceOf ("word", false, false), s5.dropLastCharacters (5));
expectEquals (s5.upToLastOccurrenceOf ("Word", false, true), s5.dropLastCharacters (5));
expectEquals (s5.replace ("word", L"xyz", false), String ("xyz xyz2 xyz3"));
expect (s5.replace (L"Word", "xyz", true) == "xyz xyz2 xyz3");
expect (s5.dropLastCharacters (1).replace ("Word", String ("xyz"), true) == L"xyz xyz2 xyz");
expect (s5.replace ("Word", "", true) == " 2 3");
expectEquals (s5.replace ("Word2", L"xyz", true), String ("word xyz word3"));
expect (s5.replaceCharacter (L'w', 'x') != s5);
expectEquals (s5.replaceCharacter ('w', L'x').replaceCharacter ('x', 'w'), s5);
expect (s5.replaceCharacters ("wo", "xy") != s5);
expectEquals (s5.replaceCharacters ("wo", "xy").replaceCharacters ("xy", L"wo"), s5);
expectEquals (s5.retainCharacters ("1wordxya"), String ("wordwordword"));
expect (s5.retainCharacters (String::empty).isEmpty());
expect (s5.removeCharacters ("1wordxya") == " 2 3");
expectEquals (s5.removeCharacters (String::empty), s5);
expect (s5.initialSectionContainingOnly ("word") == L"word");
expect (String ("word").initialSectionContainingOnly ("word") == L"word");
expectEquals (s5.initialSectionNotContaining (String ("xyz ")), String ("word"));
expectEquals (s5.initialSectionNotContaining (String (";[:'/")), s5);
expect (! s5.isQuotedString());
expect (s5.quoted().isQuotedString());
expect (! s5.quoted().unquoted().isQuotedString());
expect (! String ("x'").isQuotedString());
expect (String ("'x").isQuotedString());
String s6 (" \t xyz \t\r\n");
expectEquals (s6.trim(), String ("xyz"));
expect (s6.trim().trim() == "xyz");
expectEquals (s5.trim(), s5);
expectEquals (s6.trimStart().trimEnd(), s6.trim());
expectEquals (s6.trimStart().trimEnd(), s6.trimEnd().trimStart());
expectEquals (s6.trimStart().trimStart().trimEnd().trimEnd(), s6.trimEnd().trimStart());
expect (s6.trimStart() != s6.trimEnd());
expectEquals (("\t\r\n " + s6 + "\t\n \r").trim(), s6.trim());
expect (String::repeatedString ("xyz", 3) == L"xyzxyzxyz");
}
{
beginTestCase ("UTF conversions");
TestUTFConversion <CharPointer_UTF32>::test (*this);
TestUTFConversion <CharPointer_UTF8>::test (*this);
TestUTFConversion <CharPointer_UTF16>::test (*this);
}
{
beginTestCase ("StringArray");
StringArray s;
s.addTokens ("4,3,2,1,0", ";,", "x");
expectEquals (s.size(), 5);
expectEquals (s.joinIntoString ("-"), String ("4-3-2-1-0"));
s.remove (2);
expectEquals (s.joinIntoString ("--"), String ("4--3--1--0"));
expectEquals (s.joinIntoString (String::empty), String ("4310"));
s.clear();
expectEquals (s.joinIntoString ("x"), String::empty);
StringArray toks;
toks.addTokens ("x,,", ";,", "");
expectEquals (toks.size(), 3);
expectEquals (toks.joinIntoString ("-"), String ("x--"));
toks.clear();
toks.addTokens (",x,", ";,", "");
expectEquals (toks.size(), 3);
expectEquals (toks.joinIntoString ("-"), String ("-x-"));
toks.clear();
toks.addTokens ("x,'y,z',", ";,", "'");
expectEquals (toks.size(), 3);
expectEquals (toks.joinIntoString ("-"), String ("x-'y,z'-"));
}
}
};
static StringTests stringUnitTests;
#endif
}

View File

@@ -24,6 +24,7 @@
#ifndef BEAST_THREADS_THREAD_H_INCLUDED
#define BEAST_THREADS_THREAD_H_INCLUDED
#include "../strings/String.h"
#include "../utility/LeakChecked.h"
#include "RecursiveMutex.h"
#include "WaitableEvent.h"

View File

@@ -21,9 +21,11 @@
#include "../../BeastConfig.h"
#endif
#include "impl/Atomic.cpp"
#include "impl/RecursiveMutex.cpp"
#include "impl/ServiceQueue.cpp"
#include "impl/Stoppable.cpp"
#include "impl/Thread.cpp"
#include "impl/WaitableEvent.cpp"
#include "tests/Atomic.test.cpp"
#include "tests/ServiceQueue.test.cpp"

View File

@@ -19,8 +19,6 @@
#include "../ServiceQueue.h"
#include "../../../modules/beast_core/beast_core.h" // for UnitTest
namespace beast {
class ServiceQueueBase::ScopedServiceThread : public List <ScopedServiceThread>::Node
@@ -185,275 +183,4 @@ bool ServiceQueueBase::empty()
//
ThreadLocalValue <ServiceQueueBase*> ServiceQueueBase::s_service;
//------------------------------------------------------------------------------
namespace detail {
//------------------------------------------------------------------------------
class ServiceQueueTimingTests
: public UnitTest
{
public:
class Stopwatch
{
public:
Stopwatch () { start(); }
void start () { m_startTime = Time::getHighResolutionTicks (); }
double getElapsed ()
{
int64 const now = Time::getHighResolutionTicks();
return Time::highResolutionTicksToSeconds (now - m_startTime);
}
private:
int64 m_startTime;
};
static int const callsPerThread = 50000;
//--------------------------------------------------------------------------
template <typename ServiceType>
struct Consumer : Thread
{
ServiceType& m_service;
Random m_random;
String m_string;
Consumer (int id, int64 seedValue, ServiceType& service)
: Thread ("C#" + String::fromNumber (id))
, m_service (service)
, m_random (seedValue)
{ startThread(); }
~Consumer ()
{ stopThread(); }
static Consumer*& thread()
{
static ThreadLocalValue <Consumer*> local;
return local.get();
}
static void stop_one ()
{ thread()->signalThreadShouldExit(); }
static void handler ()
{ thread()->do_handler(); }
void do_handler()
{
String const s (String::fromNumber (m_random.nextInt()));
m_string += s;
if (m_string.length() > 100)
m_string = String::empty;
}
void run ()
{
thread() = this;
while (! threadShouldExit())
m_service.run_one();
}
};
//--------------------------------------------------------------------------
template <typename ServiceType>
struct Producer : Thread
{
ServiceType& m_service;
Random m_random;
String m_string;
Producer (int id, int64 seedValue, ServiceType& service)
: Thread ("P#" + String::fromNumber (id))
, m_service (service)
, m_random (seedValue)
{ }
~Producer ()
{ stopThread(); }
void run ()
{
for (std::size_t i = 0; i < callsPerThread; ++i)
{
String const s (String::fromNumber (m_random.nextInt()));
m_string += s;
if (m_string.length() > 100)
m_string = String::empty;
m_service.dispatch (bind (&Consumer<ServiceType>::handler));
}
}
};
//--------------------------------------------------------------------------
template <typename Allocator>
void testThreads (std::size_t nConsumers, std::size_t nProducers)
{
beginTestCase (String::fromNumber (nConsumers) + " consumers, " +
String::fromNumber (nProducers) + " producers, " +
"Allocator = " + std::string(typeid(Allocator).name()));
typedef ServiceQueueType <Allocator> ServiceType;
ServiceType service (nConsumers);
std::vector <ScopedPointer <Consumer <ServiceType> > > consumers;
std::vector <ScopedPointer <Producer <ServiceType> > > producers;
consumers.reserve (nConsumers);
producers.reserve (nProducers);
for (std::size_t i = 0; i < nConsumers; ++i)
consumers.push_back (new Consumer <ServiceType> (i + 1,
random().nextInt64(), service));
for (std::size_t i = 0; i < nProducers; ++i)
producers.push_back (new Producer <ServiceType> (i + 1,
random().nextInt64(), service));
Stopwatch t;
for (std::size_t i = 0; i < producers.size(); ++i)
producers[i]->startThread();
for (std::size_t i = 0; i < producers.size(); ++i)
producers[i]->waitForThreadToExit();
for (std::size_t i = 0; i < consumers.size(); ++i)
service.dispatch (bind (&Consumer <ServiceType>::stop_one));
for (std::size_t i = 0; i < consumers.size(); ++i)
consumers[i]->waitForThreadToExit();
double const seconds (t.getElapsed());
logMessage (String (seconds, 2) + " seconds");
pass();
}
void runTest()
{
#if 1
testThreads <std::allocator<char> > (1, 1);
testThreads <std::allocator<char> > (1, 4);
testThreads <std::allocator<char> > (1, 16);
testThreads <std::allocator<char> > (4, 1);
testThreads <std::allocator<char> > (8, 16);
#endif
#if 0
testThreads <detail::ServiceQueueAllocator<char> > (1, 1);
testThreads <detail::ServiceQueueAllocator<char> > (1, 4);
testThreads <detail::ServiceQueueAllocator<char> > (1, 16);
testThreads <detail::ServiceQueueAllocator<char> > (4, 1);
testThreads <detail::ServiceQueueAllocator<char> > (8, 16);
#endif
}
ServiceQueueTimingTests () : UnitTest ("ServiceQueueTiming", "beast", runManual)
{
}
};
static ServiceQueueTimingTests serviceQueueTimingTests;
//------------------------------------------------------------------------------
class ServiceQueueTests
: public UnitTest
{
public:
struct ServiceThread : Thread
{
Random m_random;
ServiceQueue& m_service;
String m_string;
ServiceThread (int id, int64 seedValue,
ServiceQueue& service)
: Thread ("#" + String::fromNumber (id))
, m_random (seedValue)
, m_service (service)
{
startThread();
}
~ServiceThread ()
{
stopThread();
}
static ServiceThread*& thread()
{
static ThreadLocalValue <ServiceThread*> local;
return local.get();
}
static void stop_one ()
{
thread()->signalThreadShouldExit();
}
static void handler ()
{
thread()->do_handler();
}
void do_handler()
{
#if 1
String const s (String::fromNumber (m_random.nextInt()));
m_string += s;
if (m_string.length() > 100)
m_string = String::empty;
#endif
}
void run ()
{
thread() = this;
while (! threadShouldExit())
m_service.run_one();
}
};
static std::size_t const totalCalls = 10000;
void testThreads (std::size_t n)
{
std::size_t const callsPerThread (totalCalls / n);
beginTestCase (String::fromNumber (n) + " threads");
ServiceQueue service (n);
std::vector <ScopedPointer <ServiceThread> > threads;
threads.reserve (n);
for (std::size_t i = 0; i < n; ++i)
threads.push_back (new ServiceThread (i + 1,
random().nextInt64(), service));
for (std::size_t i = n * callsPerThread; i; --i)
service.dispatch (bind (&ServiceThread::handler));
for (std::size_t i = 0; i < threads.size(); ++i)
service.dispatch (bind (&ServiceThread::stop_one));
for (std::size_t i = 0; i < threads.size(); ++i)
threads[i]->waitForThreadToExit();
pass();
}
void runTest()
{
testThreads (1);
testThreads (4);
testThreads (16);
}
ServiceQueueTests () : UnitTest ("ServiceQueue", "beast")
{
}
};
static ServiceQueueTests serviceQueueTests;
}
}

View File

@@ -22,6 +22,11 @@
//==============================================================================
#include "../Thread.h"
#include "../../smart_ptr/SharedObject.h"
#include "../../smart_ptr/SharedPtr.h"
#include "../../../modules/beast_core/time/Time.h"
#include <cassert>
namespace beast {
@@ -44,7 +49,7 @@ Thread::~Thread()
To avoid this type of nastiness, always make sure you call stopThread() before or during
your subclass's destructor.
*/
check_precondition (! isThreadRunning());
assert (! isThreadRunning());
stopThread ();
}

View File

@@ -21,15 +21,21 @@
*/
//==============================================================================
#include "../../../modules/beast_core/beast_core.h" // for UnitTest
#if BEAST_INCLUDE_BEASTCONFIG
#include "../../BeastConfig.h"
#endif
#include "../../Atomic.h"
#include "../../Arithmetic.h"
#include "../../ByteOrder.h"
#include "../../unit_test/suite.h"
namespace beast {
class AtomicTests : public UnitTest
class Atomic_test : public unit_test::suite
{
public:
AtomicTests() : UnitTest ("Atomic", "beast") {}
template <typename Type>
void testFloat ()
{
@@ -78,9 +84,9 @@ public:
testFloat <Type> ();
}
void runTest()
void run()
{
beginTestCase ("Misc");
testcase ("Misc");
char a1[7];
expect (numElementsInArray(a1) == 7);
@@ -91,43 +97,43 @@ public:
expect (ByteOrder::swap ((uint32) 0x11223344) == 0x44332211);
expect (ByteOrder::swap ((uint64) literal64bit (0x1122334455667788)) == literal64bit (0x8877665544332211));
beginTestCase ("int");
testcase ("int");
testInteger <int> ();
beginTestCase ("unsigned int");
testcase ("unsigned int");
testInteger <unsigned int> ();
beginTestCase ("int32");
testcase ("int32");
testInteger <int32> ();
beginTestCase ("uint32");
testcase ("uint32");
testInteger <uint32> ();
beginTestCase ("long");
testcase ("long");
testInteger <long> ();
beginTestCase ("void*");
testcase ("void*");
testInteger <void*> ();
beginTestCase ("int*");
testcase ("int*");
testInteger <int*> ();
beginTestCase ("float");
testcase ("float");
testFloat <float> ();
#if ! BEAST_64BIT_ATOMICS_UNAVAILABLE // 64-bit intrinsics aren't available on some old platforms
beginTestCase ("int64");
testcase ("int64");
testInteger <int64> ();
beginTestCase ("uint64");
testcase ("uint64");
testInteger <uint64> ();
beginTestCase ("double");
testcase ("double");
testFloat <double> ();
#endif
}
};
static AtomicTests atomicTests;
BEAST_DEFINE_TESTSUITE(Atomic,thread,beast);
}

View File

@@ -0,0 +1,295 @@
//------------------------------------------------------------------------------
/*
This file is part of Beast: https://github.com/vinniefalco/Beast
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
//==============================================================================
#include "../ServiceQueue.h"
#include "../../unit_test/suite.h"
#include "../../../modules/beast_core/time/Time.h"
#include "../../../modules/beast_core/maths/Random.h"
#include <functional>
#include <sstream>
namespace beast {
class ServiceQueue_timing_test : public unit_test::suite
{
public:
class Stopwatch
{
public:
Stopwatch () { start(); }
void start () { m_startTime = Time::getHighResolutionTicks (); }
double getElapsed ()
{
int64 const now = Time::getHighResolutionTicks();
return Time::highResolutionTicksToSeconds (now - m_startTime);
}
private:
int64 m_startTime;
};
static int const callsPerThread = 50000;
//--------------------------------------------------------------------------
template <typename ServiceType>
struct Consumer : Thread
{
ServiceType& m_service;
Random m_random;
String m_string;
Consumer (int id, int64 seedValue, ServiceType& service)
: Thread ("C#" + String::fromNumber (id))
, m_service (service)
, m_random (seedValue)
{ startThread(); }
~Consumer ()
{ stopThread(); }
static Consumer*& thread()
{
static ThreadLocalValue <Consumer*> local;
return local.get();
}
static void stop_one ()
{ thread()->signalThreadShouldExit(); }
static void handler ()
{ thread()->do_handler(); }
void do_handler()
{
String const s (String::fromNumber (m_random.nextInt()));
m_string += s;
if (m_string.length() > 100)
m_string = String::empty;
}
void run ()
{
thread() = this;
while (! threadShouldExit())
m_service.run_one();
}
};
//--------------------------------------------------------------------------
template <typename ServiceType>
struct Producer : Thread
{
ServiceType& m_service;
Random m_random;
String m_string;
Producer (int id, int64 seedValue, ServiceType& service)
: Thread ("P#" + String::fromNumber (id))
, m_service (service)
, m_random (seedValue)
{ }
~Producer ()
{ stopThread(); }
void run ()
{
for (std::size_t i = 0; i < callsPerThread; ++i)
{
String const s (String::fromNumber (m_random.nextInt()));
m_string += s;
if (m_string.length() > 100)
m_string = String::empty;
m_service.dispatch (std::bind (&Consumer<ServiceType>::handler));
}
}
};
//--------------------------------------------------------------------------
template <typename Allocator>
void testThreads (std::size_t nConsumers, std::size_t nProducers)
{
std::stringstream ss;
ss <<
nConsumers << " consumers, " <<
nProducers << " producers, Allocator = " <<
typeid(Allocator).name();
testcase (ss.str());
typedef ServiceQueueType <Allocator> ServiceType;
ServiceType service (nConsumers);
std::vector <std::unique_ptr <Consumer <ServiceType> > > consumers;
std::vector <std::unique_ptr <Producer <ServiceType> > > producers;
consumers.reserve (nConsumers);
producers.reserve (nProducers);
Random r;
for (std::size_t i = 0; i < nConsumers; ++i)
consumers.emplace_back (new Consumer <ServiceType> (i + 1,
r.nextInt64(), service));
for (std::size_t i = 0; i < nProducers; ++i)
producers.emplace_back (new Producer <ServiceType> (i + 1,
r.nextInt64(), service));
Stopwatch t;
for (std::size_t i = 0; i < producers.size(); ++i)
producers[i]->startThread();
for (std::size_t i = 0; i < producers.size(); ++i)
producers[i]->waitForThreadToExit();
for (std::size_t i = 0; i < consumers.size(); ++i)
service.dispatch (std::bind (&Consumer <ServiceType>::stop_one));
for (std::size_t i = 0; i < consumers.size(); ++i)
consumers[i]->waitForThreadToExit();
double const seconds (t.getElapsed());
log << seconds << " seconds";
pass();
}
void run()
{
#if 1
testThreads <std::allocator<char> > (1, 1);
testThreads <std::allocator<char> > (1, 4);
testThreads <std::allocator<char> > (1, 16);
testThreads <std::allocator<char> > (4, 1);
testThreads <std::allocator<char> > (8, 16);
#endif
#if 0
testThreads <detail::ServiceQueueAllocator<char> > (1, 1);
testThreads <detail::ServiceQueueAllocator<char> > (1, 4);
testThreads <detail::ServiceQueueAllocator<char> > (1, 16);
testThreads <detail::ServiceQueueAllocator<char> > (4, 1);
testThreads <detail::ServiceQueueAllocator<char> > (8, 16);
#endif
}
};
BEAST_DEFINE_TESTSUITE_MANUAL(ServiceQueue_timing,threads,beast);
//------------------------------------------------------------------------------
class ServiceQueue_test : public unit_test::suite
{
public:
struct ServiceThread : Thread
{
Random m_random;
ServiceQueue& m_service;
String m_string;
ServiceThread (int id, int64 seedValue,
ServiceQueue& service)
: Thread ("#" + String::fromNumber (id))
, m_random (seedValue)
, m_service (service)
{
startThread();
}
~ServiceThread ()
{
stopThread();
}
static ServiceThread*& thread()
{
static ThreadLocalValue <ServiceThread*> local;
return local.get();
}
static void stop_one ()
{
thread()->signalThreadShouldExit();
}
static void handler ()
{
thread()->do_handler();
}
void do_handler()
{
#if 1
String const s (String::fromNumber (m_random.nextInt()));
m_string += s;
if (m_string.length() > 100)
m_string = String::empty;
#endif
}
void run ()
{
thread() = this;
while (! threadShouldExit())
m_service.run_one();
}
};
static std::size_t const totalCalls = 10000;
void testThreads (std::size_t n)
{
std::stringstream ss;
ss << n << " threads";
testcase (ss.str());
Random r;
std::size_t const callsPerThread (totalCalls / n);
ServiceQueue service (n);
std::vector <std::unique_ptr <ServiceThread> > threads;
threads.reserve (n);
for (std::size_t i = 0; i < n; ++i)
threads.emplace_back (new ServiceThread (i + 1,
r.nextInt64(), service));
for (std::size_t i = n * callsPerThread; i; --i)
service.dispatch (std::bind (&ServiceThread::handler));
for (std::size_t i = 0; i < threads.size(); ++i)
service.dispatch (std::bind (&ServiceThread::stop_one));
for (std::size_t i = 0; i < threads.size(); ++i)
threads[i]->waitForThreadToExit();
pass();
}
void run()
{
testThreads (1);
testThreads (4);
testThreads (16);
}
};
BEAST_DEFINE_TESTSUITE(ServiceQueue,threads,beast);
}

35
beast/unit_test.h Normal file
View File

@@ -0,0 +1,35 @@
//------------------------------------------------------------------------------
/*
This file is part of Beast: https://github.com/vinniefalco/Beast
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
//==============================================================================
#ifndef BEAST_UNIT_TEST_H_INCLUDED
#define BEAST_UNIT_TEST_H_INCLUDED
#include "./unit_test/amount.h"
#include "./unit_test/print.h"
#include "./unit_test/global_suites.h"
#include "./unit_test/match.h"
#include "./unit_test/recorder.h"
#include "./unit_test/reporter.h"
#include "./unit_test/results.h"
#include "./unit_test/runner.h"
#include "./unit_test/suite.h"
#include "./unit_test/suite_info.h"
#include "./unit_test/suite_list.h"
#endif

View File

@@ -0,0 +1,3 @@
# beast.unit_test
This provides a framework for defining and running unit tests.

59
beast/unit_test/amount.h Normal file
View File

@@ -0,0 +1,59 @@
//------------------------------------------------------------------------------
/*
This file is part of Beast: https://github.com/vinniefalco/Beast
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
//==============================================================================
#ifndef BEAST_UNIT_TEST_AMOUNT_H_INLCUDED
#define BEAST_UNIT_TEST_AMOUNT_H_INLCUDED
#include <cstddef>
#include <ostream>
#include <string>
namespace beast {
namespace unit_test {
/** Utility for producing nicely composed output of amounts with units. */
class amount
{
private:
std::size_t n;
std::string const& what;
public:
amount (amount const&) = default;
amount& operator= (amount const&) = delete;
amount (std::size_t n_, std::string const& what_)
: n (n_)
, what (what_)
{
}
friend
std::ostream&
operator<< (std::ostream& s, amount const& t)
{
s << t.n << " " << t.what << ((t.n != 1) ? "s" : "");
return s;
}
};
} // unit_test
} // beast
#endif

View File

@@ -2,7 +2,6 @@
/*
This file is part of Beast: https://github.com/vinniefalco/Beast
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
Copyright Patrick Dehne <patrick@mysonicweb.de> (www.sonicweb-radio.de)
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
@@ -15,58 +14,64 @@
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
*/
//==============================================================================
#ifndef BEAST_VFLIB_GUISERVICEQUEUE_H_INCLUDED
#define BEAST_VFLIB_GUISERVICEQUEUE_H_INCLUDED
#include "amount.h"
#include "global_suites.h"
#include "suite.h"
#include "AppConfig.h"
#include "modules/juce_core/juce_core.h"
#include "modules/juce_events/juce_events.h"
#include "CallQueue.h"
// Include this .cpp in your project to gain access to the printing suite
namespace beast {
namespace unit_test {
class GuiServiceQueue
: public CallQueue
, private juce::AsyncUpdater
, private ThreadWithServiceQueue::EntryPoints
namespace detail {
/** A suite that prints the list of globally defined suites. */
class print_test : public suite
{
public:
explicit GuiServiceQueue (const String& name)
: CallQueue(name)
, m_thread(name)
static
std::string
prefix (suite_info const& s)
{
bassert (juce::MessageManager::getInstance()->isThisTheMessageThread());
m_thread.start (this);
if (s.manual())
return "|M| ";
return " ";
}
void close ()
void
print (suite_list &c)
{
m_thread.stop (true);
CallQueue::close ();
std::size_t manual (0);
for (auto const& s : c)
{
log <<
prefix (s) <<
s.full_name();
if (s.manual())
++manual;
}
log <<
amount (c.size(), "suite") << " total, " <<
amount (manual, "manual suite")
;
}
void enqueue (ServiceQueueBase::Item* item)
void
run()
{
CallQueue::enqueue (item);
m_thread.call (&juce::AsyncUpdater::triggerAsyncUpdate, (AsyncUpdater*)this);
log << "------------------------------------------";
print (global_suites());
log << "------------------------------------------";
pass();
}
void handleAsyncUpdate()
{
poll();
}
private:
ThreadWithServiceQueue m_thread;
};
BEAST_DEFINE_TESTSUITE_MANUAL(print,unit_test,beast);
}
#endif
}
}

View File

@@ -0,0 +1,64 @@
//------------------------------------------------------------------------------
/*
This file is part of Beast: https://github.com/vinniefalco/Beast
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
//==============================================================================
#ifndef BEAST_UNIT_TEST_GLOBAL_SUITES_H_INCLUDED
#define BEAST_UNIT_TEST_GLOBAL_SUITES_H_INCLUDED
#include "suite_list.h"
namespace beast {
namespace unit_test {
namespace detail {
// Non const container is a detail, users are not allowed to modify!
inline
suite_list&
global_suites()
{
static suite_list s;
return s;
}
// Used to insert suites during static initialization
template <class Suite>
struct global_suite_instance
{
global_suite_instance (char const* name, char const* module,
char const* library, bool manual)
{
global_suites().insert <Suite> (
name, module, library, manual);
}
};
} // detail
/** Holds suites registered during static initialization. */
inline
suite_list const&
global_suites()
{
return detail::global_suites();
}
} // unit_test
} // beast
#endif

173
beast/unit_test/match.h Normal file
View File

@@ -0,0 +1,173 @@
//------------------------------------------------------------------------------
/*
This file is part of Beast: https://github.com/vinniefalco/Beast
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
//==============================================================================
#ifndef BEAST_UNIT_TEST_MATCH_H_INLCUDED
#define BEAST_UNIT_TEST_MATCH_H_INLCUDED
#include "suite_info.h"
namespace beast {
namespace unit_test {
// Predicate for implementing matches
class selector
{
public:
enum mode_t
{
// Run all tests except manual ones
all,
// Run tests that match in any field
automatch,
// Match on suite
suite,
// Match on library
library,
// Match on module (used internally)
module,
// Match nothing (used internally)
none
};
private:
mode_t m_mode;
std::string m_pat;
std::string m_library;
public:
explicit
selector (mode_t mode, std::string const& pattern = "")
: m_mode (mode)
, m_pat (pattern)
{
if (m_mode == automatch && pattern.empty())
m_mode = all;
}
bool
operator() (suite_info const& s)
{
switch (m_mode)
{
case automatch:
// check suite
if (m_pat == s.name())
{
m_mode = none;
return true;
}
// check module
if (m_pat == s.module())
{
m_mode = module;
m_library = s.library();
return ! s.manual();
}
// check library
if (m_pat == s.library())
{
m_mode = library;
return ! s.manual();
}
return false;
case suite:
return m_pat == s.name();
case module:
return m_pat == s.module() && ! s.manual();
case library:
return m_pat == s.library() && ! s.manual();
case none:
return false;
case all:
default:
// fall through
break;
};
return ! s.manual();
}
};
//------------------------------------------------------------------------------
// Utility functions for producing predicates to select suites.
/** Returns a predicate that implements a smart matching rule.
The predicate checks the suite, module, and library fields of the
suite_info in that order. When it finds a match, it changes modes
depending on what was found:
If a suite is matched first, then only the suite is selected. The
suite may be marked manual.
If a module is matched first, then only suites from that module
and library not marked manual are selected from then on.
If a library is matched first, then only suites from that library
not marked manual are selected from then on.
*/
inline
selector
match_auto (std::string const& name)
{
return selector (selector::automatch, name);
}
/** Return a predicate that matches all suites not marked manual. */
inline
selector
match_all()
{
return selector (selector::all);
}
/** Returns a predicate that matches a specific suite. */
inline
selector
match_suite (std::string const& name)
{
return selector (selector::suite, name);
}
/** Returns a predicate that matches all suites in a library. */
inline
selector
match_library (std::string const& name)
{
return selector (selector::library, name);
}
} // unit_test
} // beast
#endif

80
beast/unit_test/print.h Normal file
View File

@@ -0,0 +1,80 @@
//------------------------------------------------------------------------------
/*
This file is part of Beast: https://github.com/vinniefalco/Beast
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
//==============================================================================
#ifndef BEAST_UNIT_TEST_PRINT_H_INLCUDED
#define BEAST_UNIT_TEST_PRINT_H_INLCUDED
#include "amount.h"
#include "results.h"
#include "../streams/abstract_ostream.h"
#include "../streams/basic_std_ostream.h"
#include <iostream>
#include <string>
namespace beast {
namespace unit_test {
/** Write test results to the specified output stream. */
/** @{ */
inline
void
print (results const& r, abstract_ostream& stream)
{
for (auto const& s : r)
{
for (auto const& c : s)
{
stream <<
s.name() <<
(c.name().empty() ? "" : ("." + c.name()));
std::size_t i (1);
for (auto const& t : c.tests)
{
if (! t.pass)
stream <<
"#" << i <<
" failed: " << t.reason;
++i;
}
}
}
stream <<
amount (r.size(), "suite") << ", " <<
amount (r.cases(), "case") << ", " <<
amount (r.total(), "test") << " total, " <<
amount (r.failed(), "failure")
;
}
inline
void
print (results const& r, std::ostream& stream = std::cout)
{
auto s (make_std_ostream (stream));
print (r, s);
}
} // unit_test
} // beast
#endif

106
beast/unit_test/recorder.h Normal file
View File

@@ -0,0 +1,106 @@
//------------------------------------------------------------------------------
/*
This file is part of Beast: https://github.com/vinniefalco/Beast
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
//==============================================================================
#ifndef BEAST_UNIT_TEST_RECORDER_H_INLCUDED
#define BEAST_UNIT_TEST_RECORDER_H_INLCUDED
#include "results.h"
#include "runner.h"
namespace beast {
namespace unit_test {
/** A test runner that stores the results. */
class recorder : public runner
{
private:
results m_results;
suite_results m_suite;
case_results m_case;
public:
recorder (recorder const&) = default;
recorder& operator= (recorder const&) = default;
recorder()
{
}
/** Returns a report with the results of all completed suites. */
results const& report() const
{
return m_results;
}
private:
virtual
void
on_suite_begin (suite_info const& info) override
{
m_suite = suite_results (info.full_name());
}
virtual
void
on_suite_end() override
{
m_results.insert (std::move (m_suite));
}
virtual
void
on_case_begin (std::string const& name) override
{
m_case = case_results (name);
}
virtual
void
on_case_end() override
{
if (m_case.tests.size() > 0)
m_suite.insert (std::move (m_case));
}
virtual
void
on_pass() override
{
m_case.tests.pass();
}
virtual
void
on_fail (std::string const& reason) override
{
m_case.tests.fail (reason);
}
virtual
void
on_log (std::string const& s) override
{
m_case.log.insert (s);
}
};
} // unit_test
} // beast
#endif

207
beast/unit_test/reporter.h Normal file
View File

@@ -0,0 +1,207 @@
//------------------------------------------------------------------------------
/*
This file is part of Beast: https://github.com/vinniefalco/Beast
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
//==============================================================================
#ifndef BEAST_UNIT_TEST_REPORTER_H_INLCUDED
#define BEAST_UNIT_TEST_REPORTER_H_INLCUDED
#include "amount.h"
#include "recorder.h"
#include "../streams/abstract_ostream.h"
#include "../streams/basic_std_ostream.h"
#include <boost/optional.hpp>
#include <boost/ref.hpp>
#include <functional>
#include <iostream>
namespace beast {
namespace unit_test {
/** A simple test runner that writes everything to a stream in real time.
The totals are output when the object is destroyed.
*/
class reporter : public runner
{
private:
struct case_results
{
std::string name;
std::size_t total;
std::size_t failed;
case_results (std::string const& name_ = "")
: name (name_)
, total (0)
, failed (0)
{
}
};
struct suite_results
{
std::string name;
std::size_t cases;
std::size_t total;
std::size_t failed;
explicit
suite_results (std::string const& name_ = "")
: name (name_)
, cases (0)
, total (0)
, failed (0)
{
}
void
add (case_results const& r)
{
++cases;
total += r.total;
failed += r.failed;
}
};
struct results
{
std::size_t suites;
std::size_t cases;
std::size_t total;
std::size_t failed;
results()
: suites (0)
, cases (0)
, total (0)
, failed (0)
{
}
void
add (suite_results const& r)
{
++suites;
total += r.total;
cases += r.cases;
failed += r.failed;
}
};
boost::optional <std_ostream> m_std_ostream;
std::reference_wrapper <abstract_ostream> m_stream;
results m_results;
suite_results m_suite;
case_results m_case;
public:
reporter (reporter const&) = delete;
reporter& operator= (reporter const&) = delete;
explicit reporter (std::ostream& stream = std::cout)
: m_std_ostream (boost::ref (stream))
, m_stream (*m_std_ostream)
{
}
~reporter()
{
m_stream.get() <<
amount (m_results.suites, "suite") << ", " <<
amount (m_results.cases, "case") << ", " <<
amount (m_results.total, "test") << " total, " <<
amount (m_results.failed, "failure")
;
}
explicit reporter (abstract_ostream& stream)
: m_stream (stream)
{
}
private:
virtual
void
on_suite_begin (suite_info const& info) override
{
m_suite = suite_results (info.full_name());
}
virtual
void
on_suite_end() override
{
m_results.add (m_suite);
}
virtual
void
on_case_begin (std::string const& name) override
{
m_case = case_results (name);
m_stream.get() <<
m_suite.name <<
(m_case.name.empty() ?
"" : (" " + m_case.name))
;
}
virtual
void
on_case_end() override
{
m_suite.add (m_case);
}
virtual
void
on_pass() override
{
++m_case.total;
}
virtual
void
on_fail (std::string const& reason) override
{
++m_case.failed;
++m_case.total;
m_stream.get() <<
"#" << m_case.total <<
" failed" <<
(reason.empty() ? "" : ": ") << reason
;
}
virtual
void
on_log (std::string const& s) override
{
m_stream.get() <<
s;
}
};
} // unit_test
} // beast
#endif

256
beast/unit_test/results.h Normal file
View File

@@ -0,0 +1,256 @@
//------------------------------------------------------------------------------
/*
This file is part of Beast: https://github.com/vinniefalco/Beast
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
//==============================================================================
#ifndef BEAST_UNIT_TEST_RESULTS_H_INLCUDED
#define BEAST_UNIT_TEST_RESULTS_H_INLCUDED
#include "../container/const_container.h"
#include <string>
#include <vector>
namespace beast {
namespace unit_test {
/** Holds a set of test condition outcomes in a testcase. */
class case_results
{
public:
/** Holds the result of evaluating one test condition. */
struct test
{
explicit test (bool pass_)
: pass (pass_)
{
}
test (bool pass_, std::string const& reason_)
: pass (pass_)
, reason (reason_)
{
}
bool pass;
std::string reason;
};
private:
class tests_t
: public const_container <std::vector <test>>
{
private:
std::size_t m_failed;
public:
tests_t ()
: m_failed (0)
{
}
/** Returns the total number of test conditions. */
std::size_t
total() const
{
return cont().size();
}
/** Returns the number of failed test conditions. */
std::size_t
failed() const
{
return m_failed;
}
/** Register a successful test condition. */
void
pass()
{
cont().emplace_back (true);
}
/** Register a failed test condition. */
void
fail (std::string const& reason = "")
{
++m_failed;
cont().emplace_back (false, reason);
}
};
class log_t
: public const_container <std::vector <std::string>>
{
public:
/** Insert a string into the log. */
void
insert (std::string const& s)
{
cont().push_back (s);
}
};
std::string m_name;
public:
explicit case_results (std::string const& name = "")
: m_name (name)
{
}
/** Returns the name of this testcase. */
std::string const&
name() const
{
return m_name;
}
/** Memberspace for a container of test condition outcomes. */
tests_t tests;
/** Memberspace for a container of testcase log messages. */
log_t log;
};
//--------------------------------------------------------------------------
/** Holds the set of testcase results in a suite. */
class suite_results
: public const_container <std::vector <case_results>>
{
private:
std::string m_name;
std::size_t m_total;
std::size_t m_failed;
public:
explicit suite_results (std::string const& name = "")
: m_name (name)
, m_total (0)
, m_failed (0)
{
}
/** Returns the name of this suite. */
std::string const&
name() const
{
return m_name;
}
/** Returns the total number of test conditions. */
std::size_t
total() const
{
return m_total;
}
/** Returns the number of failures. */
std::size_t
failed() const
{
return m_failed;
}
/** Insert a set of testcase results. */
/** @{ */
void
insert (case_results&& r)
{
cont().emplace_back (std::move (r));
m_total += r.tests.total();
m_failed += r.tests.failed();
}
void
insert (case_results const& r)
{
cont().push_back (r);
m_total += r.tests.total();
m_failed += r.tests.failed();
}
/** @} */
};
//------------------------------------------------------------------------------
// VFALCO TODO Make this a template class using scoped allocators
/** Holds the results of running a set of testsuites. */
class results
: public const_container <std::vector <suite_results>>
{
private:
std::size_t m_cases;
std::size_t m_total;
std::size_t m_failed;
public:
results()
: m_cases (0)
, m_total (0)
, m_failed (0)
{
}
/** Returns the total number of test cases. */
std::size_t
cases() const
{
return m_cases;
}
/** Returns the total number of test conditions. */
std::size_t
total() const
{
return m_total;
}
/** Returns the number of failures. */
std::size_t
failed() const
{
return m_failed;
}
/** Insert a set of suite results. */
/** @{ */
void
insert (suite_results&& r)
{
m_cases += r.size();
m_total += r.total();
m_failed += r.failed();
cont().emplace_back (std::move (r));
}
void
insert (suite_results const& r)
{
m_cases += r.size();
m_total += r.total();
m_failed += r.failed();
cont().push_back (r);
}
/** @} */
};
} // unit_test
} // beast
#endif

272
beast/unit_test/runner.h Normal file
View File

@@ -0,0 +1,272 @@
//------------------------------------------------------------------------------
/*
This file is part of Beast: https://github.com/vinniefalco/Beast
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
//==============================================================================
#ifndef BEAST_UNIT_TEST_RUNNER_H_INCLUDED
#define BEAST_UNIT_TEST_RUNNER_H_INCLUDED
#include "suite_info.h"
#include "../streams/abstract_ostream.h"
#include <cassert>
#include <string>
namespace beast {
namespace unit_test {
/** Unit test runner interface.
Derived classes can customize the reporting behavior. This interface is
injected into the unit_test class to receive the results of the tests.
*/
class runner
{
private:
// Reroutes log output to the runner
class stream_t : public abstract_ostream
{
private:
runner& m_owner;
public:
stream_t() = delete;
stream_t& operator= (stream_t const&) = delete;
stream_t (runner& owner)
: m_owner (owner)
{
}
void
write (string_type const& s)
{
m_owner.log (s);
}
};
stream_t m_stream;
bool m_default;
bool m_failed;
bool m_cond;
public:
virtual ~runner() = default;
runner (runner const&) = default;
runner& operator= (runner const&) = default;
runner()
: m_stream (*this)
, m_default (false)
, m_failed (false)
, m_cond (false)
{
}
/** Run the specified suite.
@return `true` if any conditions failed.
*/
bool
run (suite_info const& s)
{
// Enable 'default' testcase
m_default = true;
m_failed = false;
on_suite_begin (s);
s.run (*this);
// Forgot to call pass or fail.
assert (m_cond);
on_case_end();
on_suite_end();
return m_failed;
}
/** Run a sequence of suites.
The expression
`FwdIter::value_type`
must be convertible to `suite_info`.
@return `true` if any conditions failed.
*/
template <class FwdIter>
bool
run (FwdIter first, FwdIter last)
{
bool failed (false);
for (;first != last; ++first)
failed = run (*first) || failed;
return failed;
}
/** Conditionally run a sequence of suites.
pred will be called as:
@code
bool pred (suite_info const&);
@endcode
@return `true` if any conditions failed.
*/
template <class FwdIter, class Pred>
bool
run_if (FwdIter first, FwdIter last, Pred pred = Pred())
{
bool failed (false);
for (;first != last; ++first)
if (pred (*first))
failed = run (*first) || failed;
return failed;
}
/** Run all suites in a container.
@return `true` if any conditions failed.
*/
template <class SequenceContainer>
bool
run_each (SequenceContainer const& c)
{
bool failed (false);
for (auto const& s : c)
failed = run (s) || failed;
return failed;
}
/** Conditionally run suites in a container.
pred will be called as:
@code
bool pred (suite_info const&);
@endcode
@return `true` if any conditions failed.
*/
template <class SequenceContainer, class Pred>
bool
run_each_if (SequenceContainer const& c, Pred pred = Pred())
{
bool failed (false);
for (auto const& s : c)
if (pred (s))
failed = run (s) || failed;
return failed;
}
private:
//
// Overrides
//
/** Called when a new suite starts. */
virtual
void
on_suite_begin (suite_info const&)
{
}
/** Called when a suite ends. */
virtual
void
on_suite_end()
{
}
/** Called when a new case starts. */
virtual
void
on_case_begin (std::string const&)
{
}
/** Called when a new case ends. */
virtual
void
on_case_end()
{
}
/** Called for each passing condition. */
virtual
void
on_pass ()
{
}
/** Called for each failing condition. */
virtual
void
on_fail (std::string const&)
{
}
/** Called when a test logs output. */
virtual
void
on_log (std::string const&)
{
}
private:
friend class suite;
abstract_ostream&
stream()
{
return m_stream;
}
// Start a new testcase.
void
testcase (std::string const& name)
{
// Name may not be empty
assert (m_default || ! name.empty());
// Forgot to call pass or fail
assert (m_default || m_cond);
if (! m_default)
on_case_end();
m_default = false;
m_cond = false;
on_case_begin (name);
}
void
pass()
{
if (m_default)
testcase ("");
on_pass();
m_cond = true;
}
void
fail (std::string const& reason)
{
if (m_default)
testcase ("");
on_fail (reason);
m_failed = true;
m_cond = true;
}
void
log (std::string const& s)
{
if (m_default)
testcase ("");
on_log (s);
}
};
} // unit_test
} // beast
#endif

289
beast/unit_test/suite.h Normal file
View File

@@ -0,0 +1,289 @@
//------------------------------------------------------------------------------
/*
This file is part of Beast: https://github.com/vinniefalco/Beast
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
//==============================================================================
#ifndef BEAST_UNIT_TEST_SUITE_H_INCLUDED
#define BEAST_UNIT_TEST_SUITE_H_INCLUDED
#include "runner.h"
#include "../utility/noexcept.h"
#include <string>
namespace beast {
namespace unit_test {
/** A testsuite class.
Derived classes execute a series of testcases, where each testcase is
a series of pass/fail tests. To provide a unit test using this class,
derive from it and use the BEAST_DEFINE_UNIT_TEST macro in a
translation unit.
*/
class suite
{
private:
// This exception is thrown internally to stop the current suite
// in the event of a failure, if the option to stop is set.
struct abort_exception : public std::exception
{
char const*
what() const noexcept override
{
return "suite aborted on failed condition";
}
};
// Memberspace
class log_t
{
private:
friend class suite;
runner* m_runner;
runner*
operator-> ()
{
return m_runner;
}
public:
log_t ()
: m_runner (nullptr)
{
}
template <class T>
abstract_ostream::scoped_stream_type
operator<< (T const& t)
{
return m_runner->stream() << t;
}
/** Returns the raw stream used for output. */
abstract_ostream&
stream()
{
return m_runner->stream();
}
};
bool m_abort = false;
public:
/** Type for scoped stream logging.
To use this type, declare a local variable of the type
on the stack in derived class member function and construct
it from log.stream();
@code
scoped_stream ss (log.stream();
ss << "Hello" << std::endl;
ss << "world" << std::endl;
@endcode
Streams constructed in this fashion will not have the line
ending automatically appended.
Thread safety:
The scoped_stream may only be used by one thread.
Multiline output sent to the stream will be atomically
written to the underlying abstract_Ostream
*/
typedef abstract_ostream::scoped_stream_type scoped_stream;
/** Memberspace for logging. */
log_t log;
/** Invokes the test using the specified runner.
Data members are set up here instead of the constructor as a
convenience to writing the derived class to avoid repetition of
forwarded constructor arguments to the base.
Normally this is called by the framework for you.
*/
void
operator() (runner& r)
{
log.m_runner = &r;
try
{
run();
}
catch (abort_exception const&)
{
// ends the suite
}
catch (std::exception const& e)
{
fail (std::string ("unhandled exception: ") +
std::string (e.what()));
}
catch (...)
{
fail ("unhandled exception");
}
}
enum abort_t
{
no_abort_on_fail,
abort_on_fail
};
/** Open a new testcase.
A testcase is a series of evaluated test conditions. A test suite
may have multiple test cases. A test is associated with the last
opened testcase. When the test first runs, a default unnamed
case is opened. Tests with only one case may omit the call
to testcase.
@param abort If `true`, the suite will be stopped on first failure.
*/
void
testcase (std::string const& name,
abort_t abort = no_abort_on_fail)
{
m_abort = abort == abort_on_fail;
log->testcase (name);
}
/** Evaluate a test condition.
The condition is passed as a template argument instead of `bool` so
that implicit conversion is not required. The `reason` argument is
logged if the condition is false.
@return `true` if the test condition indicates success.
*/
template <class Condition>
bool
expect (Condition shouldBeTrue, std::string const& reason = "")
{
if (shouldBeTrue)
pass();
else
fail (reason);
return shouldBeTrue;
}
// DEPRECATED
// @return `true` if the test condition indicates success (a false value)
template <class Condition>
bool
unexpected (Condition shouldBeFalse, std::string const& reason = "")
{
if (! shouldBeFalse)
pass();
else
fail (reason);
return ! shouldBeFalse;
}
/** Record a successful test condition. */
void
pass()
{
log->pass();
}
/** Record a failure. */
void
fail (std::string const& reason= "")
{
log->fail (reason);
if (m_abort)
throw abort_exception();
}
private:
/** Runs the suite. */
virtual
void
run() = 0;
};
} // unit_test
} // beast
//------------------------------------------------------------------------------
// detail:
// This inserts the suite with the given manual flag
#define BEAST_DEFINE_TESTSUITE_INSERT(Class,Module,Library,manual) \
static beast::unit_test::detail::global_suite_instance <Class##_test> \
Library ## Module ## Class ## _test_instance ( \
#Class, #Module, #Library, manual);
//------------------------------------------------------------------------------
// Preprocessor directives for controlling unit test definitions.
// If this is already defined, don't redefine it. This allows
// programs to provide custom behavior for testsuite definitions
//
#ifndef BEAST_DEFINE_TESTSUITE
/** Enables insertion of test suites into the global container.
The default is to insert all test suite definitions into the global
container. If BEAST_DEFINE_TESTSUITE is user defined, this macro
has no effect.
*/
#ifndef BEAST_NO_UNIT_TEST_INLINE
#define BEAST_NO_UNIT_TEST_INLINE 0
#endif
/** Define a unit test suite.
Class The type representing the class being tested.
Module Identifies the module.
Library Identifies the library.
The declaration for the class implementing the test should be the same
as Class ## _test. For example, if Class is aged_ordered_container, the
test class must be declared as:
@code
struct aged_ordered_container_test : beast::unit_test::suite
{
//...
};
@endcode
The macro invocation must appear in the same namespace as the test class.
*/
#if BEAST_NO_UNIT_TEST_INLINE
#define BEAST_DEFINE_TESTSUITE(Class,Module,Library)
#else
#include "global_suites.h"
#define BEAST_DEFINE_TESTSUITE(Class,Module,Library) \
BEAST_DEFINE_TESTSUITE_INSERT(Class,Module,Library,false)
#define BEAST_DEFINE_TESTSUITE_MANUAL(Class,Module,Library) \
BEAST_DEFINE_TESTSUITE_INSERT(Class,Module,Library,true)
#endif
#endif
//------------------------------------------------------------------------------
#endif

View File

@@ -0,0 +1,125 @@
//------------------------------------------------------------------------------
/*
This file is part of Beast: https://github.com/vinniefalco/Beast
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
//==============================================================================
#ifndef BEAST_UNIT_TEST_SUITE_INFO_H_INCLUDED
#define BEAST_UNIT_TEST_SUITE_INFO_H_INCLUDED
#include <functional>
#include <string>
#include <utility>
namespace beast {
namespace unit_test {
class runner;
/** Associates a unit test type with metadata. */
class suite_info
{
private:
typedef std::function <void (runner&)> run_type;
char const* m_name;
char const* m_module;
char const* m_library;
bool m_manual;
run_type m_run;
public:
suite_info (
char const* name,
char const* module,
char const* library,
bool manual,
run_type run)
: m_name (name)
, m_module (module)
, m_library (library)
, m_manual (manual)
, m_run (std::move (run))
{
}
char const*
name() const
{
return m_name;
}
char const*
module() const
{
return m_module;
}
char const*
library() const
{
return m_library;
}
/** Returns `true` if this suite only runs manually. */
bool
manual() const
{
return m_manual;
}
/** Return the canonical suite name as a string. */
std::string
full_name() const
{
return
std::string (m_library) + "." +
std::string (m_module) + "." +
std::string (m_name);
}
/** Run a new instance of the associated test suite. */
void
run (runner& r) const
{
m_run (r);
}
};
inline
bool
operator< (suite_info const& lhs, suite_info const& rhs)
{
return lhs.full_name() < rhs.full_name();
}
/** Convenience for producing suite_info for a given test type. */
template <class Suite>
suite_info make_suite_info (char const* name, char const* module,
char const* library, bool manual)
{
return suite_info (name, module, library, manual,
[](runner& r)
{
Suite test;
return test (r);
});
}
} // unit_test
} // beast
#endif

View File

@@ -0,0 +1,81 @@
//------------------------------------------------------------------------------
/*
This file is part of Beast: https://github.com/vinniefalco/Beast
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
//==============================================================================
#ifndef BEAST_UNIT_TEST_SUITE_LIST_H_INCLUDED
#define BEAST_UNIT_TEST_SUITE_LIST_H_INCLUDED
#include "suite_info.h"
#include "../container/const_container.h"
#include <cassert>
//#include <list>
#include <typeindex>
#include <set>
#include <unordered_set>
namespace beast {
namespace unit_test {
/** A container of test suites. */
class suite_list
: public const_container <
std::set <suite_info>
//std::list <suite_info>
>
{
private:
#ifndef NDEBUG
std::unordered_set <std::string> m_names;
std::unordered_set <std::type_index> m_classes;
#endif
public:
/** Insert a suite into the set.
The suite must not already exist.
*/
template <class Suite>
void
insert (char const* name,
char const* module, char const* library,
bool manual)
{
#ifndef NDEBUG
{
auto const result (m_names.insert (name));
assert (result.second); // Duplicate name
}
{
auto const result (m_classes.insert (
std::type_index (typeid(Suite))));
assert (result.second); // Duplicate type
}
#endif
cont().emplace (std::move (make_suite_info <Suite> (
name, module, library, manual)));
}
};
} // unit_test
} // beast
#endif

View File

@@ -26,10 +26,11 @@
// For Journal and Debug
#include "../../modules/beast_core/beast_core.h"
#include "impl/Assert.cpp"
#include "impl/Debug.cpp"
#include "impl/Journal.cpp"
#include "impl/LeakChecked.cpp"
#include "impl/StaticObject.cpp"
#include "impl/PropertyStream.cpp"
#include "tests/bassert.test.cpp"
#include "tests/empty_base_optimization.test.cpp"

View File

@@ -17,6 +17,9 @@
*/
//==============================================================================
#include "../Debug.h"
#include "../../unit_test/suite.h"
namespace beast {
namespace Debug {
@@ -299,7 +302,7 @@ String commandLineToString (const String& commandLine)
// A simple unit test to determine the diagnostic settings in a build.
//
class DebugTests : public UnitTest
class Debug_test : public unit_test::suite
{
public:
static int envDebug ()
@@ -329,25 +332,34 @@ public:
#endif
}
void runTest ()
void run ()
{
beginTestCase ("diagnostics");
log <<
"operatingSystemName = '" <<
SystemStats::getOperatingSystemName () << "'";
log <<
"_DEBUG = " <<
String::fromNumber (envDebug ());
log <<
"BEAST_DEBUG = " <<
String::fromNumber (beastDebug ());
log <<
"BEAST_FORCE_DEBUG = " <<
String::fromNumber (beastForceDebug ());
log <<
"sizeof(std::size_t) = " <<
String::fromNumber (sizeof(std::size_t));
logMessage ("operatingSystemName = '" + SystemStats::getOperatingSystemName () + "'");
logMessage ("_DEBUG = " + String::fromNumber (envDebug ()));
logMessage ("BEAST_DEBUG = " + String::fromNumber (beastDebug ()));
logMessage ("BEAST_FORCE_DEBUG = " + String::fromNumber (beastForceDebug ()));
logMessage ("sizeof(std::size_t) = " + String::fromNumber (sizeof(std::size_t)));
bassertfalse;
fail ();
}
DebugTests () : UnitTest ("Debug", "beast", runManual)
{
}
};
static DebugTests debugTests;
BEAST_DEFINE_TESTSUITE_MANUAL(Debug,utility,beast);
}

View File

@@ -18,6 +18,7 @@
//==============================================================================
#include "../PropertyStream.h"
#include "../../unit_test/suite.h"
#include <limits>
#include <iostream>
@@ -606,7 +607,7 @@ void PropertyStream::add (long double value)
//------------------------------------------------------------------------------
class PropertyStreamTests : public UnitTest
class PropertyStream_test : public unit_test::suite
{
public:
typedef PropertyStream::Source Source;
@@ -622,7 +623,7 @@ public:
}
catch (...)
{
failException ();
fail ("unhandled exception");;
}
}
@@ -637,7 +638,7 @@ public:
}
catch(...)
{
failException ();
fail ("unhandled exception");;
}
}
@@ -652,7 +653,7 @@ public:
}
catch (...)
{
failException ();
fail ("unhandled exception");;
}
}
@@ -665,7 +666,7 @@ public:
}
catch (...)
{
failException ();
fail ("unhandled exception");;
}
}
@@ -679,7 +680,7 @@ public:
}
catch (...)
{
failException ();
fail ("unhandled exception");;
}
}
@@ -693,7 +694,7 @@ public:
}
catch(...)
{
failException ();
fail ("unhandled exception");;
}
}
@@ -708,11 +709,11 @@ public:
}
catch (...)
{
failException ();
fail ("unhandled exception");;
}
}
void runTest()
void run()
{
Source a ("a");
Source b ("b");
@@ -733,19 +734,19 @@ public:
b.add ( e );
d.add ( f );
beginTestCase ("peel_name");
testcase ("peel_name");
test_peel_name ("a", "a", "");
test_peel_name ("foo/bar", "foo", "bar");
test_peel_name ("foo/goo/bar", "foo", "goo/bar");
test_peel_name ("", "", "");
beginTestCase ("peel_leading_slash");
testcase ("peel_leading_slash");
test_peel_leading_slash ("foo/", "foo/", false);
test_peel_leading_slash ("foo", "foo", false);
test_peel_leading_slash ("/foo/", "foo/", true);
test_peel_leading_slash ("/foo", "foo", true);
beginTestCase ("peel_trailing_slashstar");
testcase ("peel_trailing_slashstar");
test_peel_trailing_slashstar ("/foo/goo/*", "/foo/goo", true);
test_peel_trailing_slashstar ("foo/goo/*", "foo/goo", true);
test_peel_trailing_slashstar ("/foo/goo/", "/foo/goo", false);
@@ -757,13 +758,13 @@ public:
test_peel_trailing_slashstar ("**", "*", true);
test_peel_trailing_slashstar ("*/", "*", false);
beginTestCase ("find_one");
testcase ("find_one");
test_find_one (a, &b, "b");
test_find_one (a, nullptr, "d");
test_find_one (b, &e, "e");
test_find_one (d, &f, "f");
beginTestCase ("find_path");
testcase ("find_path");
test_find_path (a, "a", nullptr);
test_find_path (a, "e", nullptr);
test_find_path (a, "a/b", nullptr);
@@ -774,14 +775,14 @@ public:
test_find_path (a, "b/e", &e);
test_find_path (a, "b/d/f", &f);
beginTestCase ("find_one_deep");
testcase ("find_one_deep");
test_find_one_deep (a, "z", nullptr);
test_find_one_deep (a, "g", &g);
test_find_one_deep (a, "b", &b);
test_find_one_deep (a, "d", &d);
test_find_one_deep (a, "f", &f);
beginTestCase ("find");
testcase ("find");
test_find (a, "", &a, false);
test_find (a, "*", &a, true);
test_find (a, "/b", &b, false);
@@ -798,14 +799,9 @@ public:
test_find (a, "/d*", nullptr, true);
test_find (a, "/d/*", nullptr, true);
}
PropertyStreamTests ()
: UnitTest ("PropertyStream", "beast")
{
}
};
static PropertyStreamTests propertyStreamTests;
BEAST_DEFINE_TESTSUITE(PropertyStream,utility,beast);
}

View File

@@ -17,21 +17,23 @@
*/
//==============================================================================
#include "../../Config.h"
#include "../../unit_test/suite.h"
namespace beast {
class BassertUnitTests : public UnitTest
// This demonstrates what happens when a bassert condition fails
class bassert_test : public unit_test::suite
{
public:
void runTest ()
void run ()
{
beginTestCase ("bassert");
bassert (false);
pass();
}
BassertUnitTests () : UnitTest ("bassert", "beast", runManual) { }
};
//------------------------------------------------------------------------------
BEAST_DEFINE_TESTSUITE_MANUAL(bassert,utility,beast);
static BassertUnitTests bassertUnitTests;
}
} // beast

View File

@@ -23,12 +23,12 @@
#include "../empty_base_optimization.h"
#include "../../../modules/beast_core/beast_core.h" // for UnitTest
#include "../../unit_test/suite.h"
namespace beast {
class empty_base_optimization_Tests
: public UnitTest
class empty_base_optimization_test
: public unit_test::suite
{
public:
template <class T>
@@ -94,20 +94,14 @@ public:
}
void
runTest ()
run ()
{
beginTestCase ("empty_base_optimization");
expect (test_one());
expect (test_two());
pass ();
}
empty_base_optimization_Tests()
: UnitTest ("empty_base_optimization", "beast")
{
}
};
static empty_base_optimization_Tests empty_base_optimization_tests;
BEAST_DEFINE_TESTSUITE(empty_base_optimization,utility,beast);
} // beast

View File

@@ -51,8 +51,6 @@
#include "tests/TestPeerLogicAsyncClient.cpp"
#include "tests/TestPeerUnitTests.cpp"
#include "system/BoostUnitTests.cpp"
#include "http/HTTPParser.cpp"
#include "http/HTTPRequestParser.cpp"
#include "http/HTTPResponseParser.cpp"

View File

@@ -19,6 +19,7 @@
#include "../../../beast/asio/wrap_handler.h"
#include "../../../beast/asio/placeholders.h"
#include "../../../beast/unit_test/suite.h"
namespace beast {
namespace asio {
@@ -545,7 +546,7 @@ HTTPClientBase* HTTPClientBase::New (Journal journal,
//------------------------------------------------------------------------------
class HTTPClientTests : public UnitTest
class HTTPClient_test : public unit_test::suite
{
public:
typedef boost::system::error_code error_code;
@@ -592,35 +593,38 @@ public:
//--------------------------------------------------------------------------
void log (HTTPMessage const& m)
void print (HTTPMessage const& m)
{
for (std::size_t i = 0; i < m.headers().size(); ++i)
{
HTTPField const f (m.headers()[i]);
String s;
s = "[ '" + f.name() +
"' , '" + f.value() + "' ]";
logMessage (s);
std::stringstream ss;
log <<
"[ '" << f.name() <<
"' , '" << f.value() + "' ]";
}
}
void log (HTTPClientBase::error_type error, HTTPClientBase::value_type const& response)
void print (HTTPClientBase::error_type error,
HTTPClientBase::value_type const& response)
{
if (error != 0)
{
logMessage (String (
"HTTPClient error: '" + error.message() + "'"));
log <<
"HTTPClient error: '" + error.message() << "'";
}
else if (! response.empty ())
{
logMessage (String ("Status: ") +
String::fromNumber (response->status()));
log <<
"Status: " <<
String::fromNumber (response->status()).toStdString();
log (*response);
print (*response);
}
else
{
logMessage ("HTTPClient: no response");
log <<
"HTTPClient: no response";
}
}
@@ -628,7 +632,7 @@ public:
void handle_get (HTTPClientBase::result_type result)
{
log (result.first, result.second);
print (result.first, result.second);
}
void testSync (String const& s, double timeoutSeconds)
@@ -639,7 +643,7 @@ public:
HTTPClientBase::result_type const& result (
client->get (ParsedURL (s).url ()));
log (result.first, result.second);
print (result.first, result.second);
}
void testAsync (String const& s, double timeoutSeconds)
@@ -649,7 +653,7 @@ public:
HTTPClientBase::New (Journal(), timeoutSeconds));
client->async_get (t.get_io_service (), ParsedURL (s).url (),
beast::bind (&HTTPClientTests::handle_get, this,
beast::bind (&HTTPClient_test::handle_get, this,
beast::_1));
t.start ();
@@ -658,10 +662,8 @@ public:
//--------------------------------------------------------------------------
void runTest ()
void run ()
{
beginTestCase ("HTTPClient::get");
testSync (
"http://www.boost.org/doc/libs/1_54_0/doc/html/boost_asio/reference.html",
5);
@@ -676,13 +678,9 @@ public:
pass ();
}
HTTPClientTests () : UnitTest ("HttpClient", "beast", runManual)
{
}
};
static HTTPClientTests httpClientTests;
BEAST_DEFINE_TESTSUITE_MANUAL(HTTPClient,beast_asio,beast);
}
}

View File

@@ -52,33 +52,9 @@
#include <boost/type_traits.hpp>
#include <boost/asio/detail/handler_alloc_helpers.hpp>
#include <boost/asio/detail/handler_invoke_helpers.hpp>
#include <boost/asio/detail/handler_cont_helpers.hpp>
// work-around for broken <boost/get_pointer.hpp>
#include "../../../beast/boost/get_pointer.h"
// Continuation hooks added in 1.54.0
#ifndef BEAST_ASIO_HAS_CONTINUATION_HOOKS
# if BOOST_VERSION >= 105400
# define BEAST_ASIO_HAS_CONTINUATION_HOOKS 1
# else
# define BEAST_ASIO_HAS_CONTINUATION_HOOKS 0
# endif
#endif
#if BEAST_ASIO_HAS_CONTINUATION_HOOKS
# include <boost/asio/detail/handler_cont_helpers.hpp>
#endif
//------------------------------------------------------------------------------
// Configure some options based on the version of boost
#if BOOST_VERSION >= 105400
# ifndef BEAST_ASIO_HAS_BUFFEREDHANDSHAKE
# define BEAST_ASIO_HAS_BUFFEREDHANDSHAKE 1
# endif
#else
# ifndef BEAST_ASIO_HAS_BUFFEREDHANDSHAKE
# define BEAST_ASIO_HAS_BUFFEREDHANDSHAKE 0
# endif
#endif
#endif

View File

@@ -1,86 +0,0 @@
//------------------------------------------------------------------------------
/*
This file is part of Beast: https://github.com/vinniefalco/Beast
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
//==============================================================================
namespace beast {
/** Test for showing information about the build of boost.
*/
class BoostUnitTests : public UnitTest
{
public:
struct BoostVersion
{
explicit BoostVersion (int value)
: vmajor (value / 100000)
, vminor ((value / 100) % 100)
, vpatch (value % 100)
{
}
String toString () const noexcept
{
return String (vmajor) + "." +
String (vminor).paddedLeft ('0', 2) + "." +
String (vpatch).paddedLeft ('0', 2);
}
int vmajor;
int vminor;
int vpatch;
};
enum
{
minimumVersion = 104700
};
// To prevent constant conditional expression warning
static int getMinimumVersion ()
{
return minimumVersion;
}
void runTest ()
{
beginTestCase ("version");
BoostVersion version (BOOST_VERSION);
logMessage (String ("BOOST_VERSION = " + version.toString ()));
logMessage (String ("BOOST_LIB_VERSION = '") + BOOST_LIB_VERSION + "'");
if (BOOST_VERSION >= getMinimumVersion ())
{
pass ();
}
else
{
fail (String ("Boost version is below ") +
BoostVersion (minimumVersion).toString ());
}
}
BoostUnitTests () : UnitTest ("boost", "beast")
{
}
};
static BoostUnitTests boostUnitTests;
}

View File

@@ -65,11 +65,14 @@ String PeerTest::Result::message () const noexcept
return m_message;
}
bool PeerTest::Result::report (UnitTest& test, bool reportPassingTests) const
bool PeerTest::Result::report (unit_test::suite& suite,
bool reportPassingTests) const
{
bool const success = test.unexpected (failed (), message ());
bool const success = suite.expect (! failed (),
message ().toStdString());
if (reportPassingTests && success)
test.logMessage (String ("pass ") + message());
suite.log <<
"pass " + message().toStdString();
return success;
}
@@ -90,14 +93,15 @@ bool PeerTest::Results::operator!= (Results const& other) const noexcept
return (client != other.client) || (server != other.server);
}
bool PeerTest::Results::report (UnitTest& test, bool beginTestCase) const
bool PeerTest::Results::report (unit_test::suite& suite,
bool beginTestCase) const
{
if (beginTestCase)
test.beginTestCase (name);
suite.testcase (name.toStdString());
bool success = true;
if (! client.report (test))
if (! client.report (suite))
success = false;
if (! server.report (test))
if (! server.report (suite))
success = false;
return success;
}

View File

@@ -20,6 +20,8 @@
#ifndef BEAST_ASIO_TESTS_PEERTEST_H_INCLUDED
#define BEAST_ASIO_TESTS_PEERTEST_H_INCLUDED
#include "../../../beast/unit_test/suite.h"
namespace beast {
namespace asio {
@@ -67,14 +69,15 @@ public:
bool timedout () const noexcept;
/** Provides a descriptive message.
This is suitable to pass to UnitTest::fail.
This is suitable to pass to suite::fail.
*/
String message () const noexcept;
/** Report the result to a UnitTest object.
/** Report the result to a testsuite.
A return value of true indicates success.
*/
bool report (UnitTest& test, bool reportPassingTests = false) const;
bool report (unit_test::suite& suite,
bool reportPassingTests = false) const;
private:
boost::system::error_code m_ec;
@@ -97,19 +100,21 @@ public:
bool operator== (Results const& other) const noexcept;
bool operator!= (Results const& other) const noexcept;
/** Report the results to a UnitTest object.
/** Report the results to a suite object.
A return value of true indicates success.
@param beginTestCase `true` to call test.beginTestCase for you
*/
bool report (UnitTest& test, bool beginTestCase = true) const;
bool report (unit_test::suite& suite, bool beginTestCase = true) const;
};
//--------------------------------------------------------------------------
/** Test two peers and return the results.
*/
template <typename Details, typename ClientLogic, typename ServerLogic, typename ClientArg, typename ServerArg>
static Results run (ClientArg const& clientArg, ServerArg const& serverArg, int timeoutSeconds = defaultTimeoutSeconds)
template <class Details, class ClientLogic, class ServerLogic,
class ClientArg, class ServerArg>
static Results run (ClientArg const& clientArg, ServerArg const& serverArg,
int timeoutSeconds = defaultTimeoutSeconds)
{
Results results;
@@ -199,42 +204,40 @@ public:
return results;
}
template <typename Details, typename ClientLogic, typename ServerLogic, class Arg>
template <class Details, class ClientLogic, class ServerLogic, class Arg>
static Results run (Arg const& arg, int timeoutSeconds = defaultTimeoutSeconds)
{
return run <Details, ClientLogic, ServerLogic, Arg, Arg> (arg, arg, timeoutSeconds);
return run <Details, ClientLogic, ServerLogic, Arg, Arg> (
arg, arg, timeoutSeconds);
}
//--------------------------------------------------------------------------
/** Reports tests of Details for all known asynchronous logic combinations to a UnitTest.
*/
template <typename Details, class Arg>
static void report_async (UnitTest& test, Arg const& arg,
template <class Details, class Arg>
static void report_async (unit_test::suite& suite, Arg const& arg,
int timeoutSeconds = defaultTimeoutSeconds,
bool beginTestCase = true)
{
run <Details, TestPeerLogicAsyncClient, TestPeerLogicAsyncServer>
(arg, timeoutSeconds).report (test, beginTestCase);
(arg, timeoutSeconds).report (suite, beginTestCase);
}
/** Reports tests of Details against all known logic combinations to a UnitTest.
*/
template <typename Details, class Arg>
static void report (UnitTest& test, Arg const& arg,
int timeoutSeconds = defaultTimeoutSeconds,
bool beginTestCase = true)
template <class Details, class Arg>
static
void
report (unit_test::suite& suite, Arg const& arg,
int timeoutSeconds = defaultTimeoutSeconds, bool beginTestCase = true)
{
run <Details, TestPeerLogicSyncClient, TestPeerLogicSyncServer>
(arg, timeoutSeconds).report (test, beginTestCase);
(arg, timeoutSeconds).report (suite, beginTestCase);
run <Details, TestPeerLogicAsyncClient, TestPeerLogicSyncServer>
(arg, timeoutSeconds).report (test, beginTestCase);
(arg, timeoutSeconds).report (suite, beginTestCase);
run <Details, TestPeerLogicSyncClient, TestPeerLogicAsyncServer>
(arg, timeoutSeconds).report (test, beginTestCase);
(arg, timeoutSeconds).report (suite, beginTestCase);
report_async <Details> (test, arg, timeoutSeconds, beginTestCase);
report_async <Details> (suite, arg, timeoutSeconds, beginTestCase);
}
};

View File

@@ -17,11 +17,13 @@
*/
//==============================================================================
#include "../../../beast/unit_test/suite.h"
namespace beast {
namespace asio {
/** UnitTest for the TestPeer family of objects. */
class TestPeerUnitTests : public UnitTest
/** Test suite for the TestPeer family of objects. */
class TestPeer_test : public unit_test::suite
{
public:
@@ -31,7 +33,7 @@ public:
PeerTest::report <Details> (*this, arg, timeoutSeconds);
}
void runTest ()
void run ()
{
typedef boost::asio::ip::tcp protocol;
testDetails <TcpDetails, TcpDetails::arg_type> (protocol::v4 ());
@@ -44,13 +46,9 @@ public:
{
timeoutSeconds = 10
};
TestPeerUnitTests () : UnitTest ("TestPeer", "beast")
{
}
};
static TestPeerUnitTests testPeerUnitTests;
BEAST_DEFINE_TESTSUITE(TestPeer,beast_asio,beast);
}
}

View File

@@ -128,7 +128,6 @@
#include "diagnostic/FatalError.cpp"
#include "diagnostic/SemanticVersion.cpp"
#include "diagnostic/UnitTest.cpp"
#include "diagnostic/UnitTestUtilities.cpp"
#include "files/DirectoryIterator.cpp"
@@ -145,7 +144,6 @@
#include "memory/MemoryBlock.cpp"
#include "misc/Main.cpp"
#include "misc/Result.cpp"
#include "streams/FileInputSource.cpp"

View File

@@ -166,7 +166,6 @@ class FileOutputStream;
#include "files/TemporaryFile.h"
#include "logging/Logger.h"
#include "memory/SharedSingleton.h"
#include "misc/Main.h"
#include "misc/WindowsRegistry.h"
#include "streams/MemoryOutputStream.h"
@@ -177,7 +176,6 @@ class FileOutputStream;
#include "threads/HighResolutionTimer.h"
#include "threads/InterProcessLock.h"
#include "threads/Process.h"
#include "diagnostic/UnitTest.h"
#include "xml/XmlDocument.h"
#include "xml/XmlElement.h"
#include "diagnostic/UnitTestUtilities.h"

View File

@@ -17,8 +17,9 @@
*/
//==============================================================================
namespace beast
{
#include "../../../beast/unit_test/suite.h"
namespace beast {
//
// FatalError::Reporter
@@ -112,26 +113,16 @@ FatalError::FatalError (char const* message, char const* fileName, int lineNumbe
//------------------------------------------------------------------------------
// Yes even this class can have a unit test. It's manually triggered though.
//
class FatalErrorTests : public UnitTest
class FatalError_test : public unit_test::suite
{
public:
FatalErrorTests () : UnitTest ("FatalError", "beast", runManual)
void run ()
{
}
void runTest ()
{
beginTestCase ("raise");
// We don't really expect the program to run after this
// but the unit test is here so you can manually test it.
int shouldBeZero (1);
check_invariant (shouldBeZero == 0);
}
};
static FatalErrorTests fatalErrorTests;
BEAST_DEFINE_TESTSUITE_MANUAL(FatalError,beast_core,beast);
} // namespace beast
} // beast

View File

@@ -17,8 +17,9 @@
*/
//==============================================================================
namespace beast
{
#include "../../../beast/unit_test/suite.h"
namespace beast {
SemanticVersion::SemanticVersion ()
: majorVersion (0)
@@ -288,13 +289,9 @@ bool SemanticVersion::chopIdentifiers (StringArray* value, bool allowLeadingZero
//------------------------------------------------------------------------------
class SemanticVersionTests : public UnitTest
class SemanticVersion_test: public unit_test::suite
{
public:
SemanticVersionTests () : UnitTest ("SemanticVersion", "beast")
{
}
void checkPass (String const& input, bool shouldPass = true)
{
SemanticVersion v;
@@ -377,7 +374,7 @@ public:
void testParse ()
{
beginTestCase ("parse");
testcase ("parse");
check ("0.0.0");
check ("1.2.3");
@@ -511,7 +508,7 @@ public:
checkLess ("0.9.9", "1.0.0");
}
void runTest ()
void run ()
{
testParse ();
testValues ();
@@ -519,6 +516,6 @@ public:
}
};
static SemanticVersionTests semanticVersionTests;
BEAST_DEFINE_TESTSUITE(SemanticVersion,beast_core,beast);
} // namespace beast
} // beast

View File

@@ -1,484 +0,0 @@
//------------------------------------------------------------------------------
/*
This file is part of Beast: https://github.com/vinniefalco/Beast
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
Portions of this file are from JUCE.
Copyright (c) 2013 - Raw Material Software Ltd.
Please visit http://www.juce.com
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
//==============================================================================
namespace beast
{
UnitTest::UnitTest (String const& className,
String const& packageName,
When when)
: m_className (className.removeCharacters (" "))
, m_packageName (packageName.removeCharacters (" "))
, m_when (when)
, m_runner (nullptr)
{
getAllTests().add (this);
}
UnitTest::~UnitTest()
{
getAllTests().removeFirstMatchingValue (this);
}
String UnitTest::getTestName() const noexcept
{
String s;
s << m_packageName << "." << m_className;
return s;
}
String const& UnitTest::getClassName() const noexcept
{
return m_className;
}
String const& UnitTest::getPackageName() const noexcept
{
return m_packageName;
}
Journal UnitTest::journal () const
{
bassert (m_runner != nullptr);
return m_runner->journal();
}
UnitTest::TestList& UnitTest::getAllTests()
{
static TestList s_tests;
return s_tests;
}
void UnitTest::initialise()
{
}
void UnitTest::shutdown()
{
}
ScopedPointer <UnitTest::Suite>& UnitTest::run (
UnitTests* const runner)
{
bassert (runner != nullptr);
m_runner = runner;
m_random = m_runner->m_random;
m_suite = new Suite (m_className, m_packageName);
initialise();
#if 0
try
{
runTest();
}
catch (...)
{
failException ();
}
#else
runTest ();
#endif
shutdown();
finishCase ();
m_suite->secondsElapsed = RelativeTime (
Time::getCurrentTime () - m_suite->whenStarted).inSeconds ();
return m_suite;
}
void UnitTest::logMessage (String const& message)
{
m_runner->logMessage (message);
}
void UnitTest::logReport (StringArray const& report)
{
m_runner->logReport (report);
}
void UnitTest::beginTestCase (String const& name)
{
finishCase ();
String s;
s << getTestName () << " : " << name;
logMessage (s);
m_case = new Case (name, m_className);
}
bool UnitTest::expect_bool (bool trueCondition, String const& failureMessage)
{
if (trueCondition)
{
pass ();
}
else
{
fail (failureMessage);
}
return trueCondition;
}
bool UnitTest::unexpected_bool (bool falseCondition, String const& failureMessage)
{
return expect (! falseCondition, failureMessage);
}
void UnitTest::pass ()
{
// If this goes off it means you forgot to call beginTestCase()!
bassert (m_case != nullptr);
m_case->items.add (Item (true));
}
void UnitTest::fail (String const& failureMessage)
{
// If this goes off it means you forgot to call beginTestCase()!
bassert (m_case != nullptr);
Item item (false, failureMessage);
m_case->failures++;
int const caseNumber = m_case->items.add (Item (false, failureMessage));
String s;
s << "#" << String (caseNumber) << " failed: " << failureMessage;
logMessage (s);
m_runner->onFailure ();
}
void UnitTest::failException ()
{
Item item (false, "An exception was thrown");
if (m_case != nullptr)
{
m_case->failures++;
}
else
{
// This hack gives us a test case, to handle the condition where an
// exception was thrown before beginTestCase() was called.
//
beginTestCase ("Exception outside test case");
}
int const caseNumber = m_case->items.add (item);
String s;
s << "#" << String (caseNumber) << " threw an exception ";
logMessage (s);
m_runner->onFailure ();
}
Random& UnitTest::random()
{
// This method's only valid while the test is being run!
bassert (m_runner != nullptr);
return m_random;
}
//------------------------------------------------------------------------------
void UnitTest::finishCase ()
{
if (m_case != nullptr)
{
// If this goes off it means you forgot to
// report any passing test case items!
//
bassert (m_case->items.size () > 0);
m_case->secondsElapsed = RelativeTime (
Time::getCurrentTime () - m_case->whenStarted).inSeconds ();
m_suite->tests += m_case->items.size ();
m_suite->failures += m_case->failures;
m_suite->cases.add (m_case.release ());
}
}
//==============================================================================
UnitTests::JournalSink::JournalSink (UnitTests& tests)
: m_tests (tests)
{
}
void UnitTests::JournalSink::write (Journal::Severity, std::string const& text)
{
m_tests.logMessage (text);
}
//==============================================================================
UnitTests::UnitTests()
: m_assertOnFailure (false)
, m_sink (*this)
{
}
UnitTests::~UnitTests()
{
}
void UnitTests::setAssertOnFailure (bool shouldAssert) noexcept
{
m_assertOnFailure = shouldAssert;
}
UnitTests::Results const& UnitTests::getResults () const noexcept
{
return *m_results;
}
bool UnitTests::anyTestsFailed () const noexcept
{
return m_results->failures > 0;
}
UnitTests::TestList UnitTests::selectTests (
String const& match, TestList const& tests) const noexcept
{
TestList list;
list.ensureStorageAllocated (tests.size ());
int const indexOfDot = match.indexOfChar ('.');
String const package = (indexOfDot == -1) ? match : match.substring (0, indexOfDot);
String const testname = (indexOfDot == -1) ? ""
: match.substring (indexOfDot + 1, match.length () + 1);
if (package != String::empty)
{
if (testname != String::empty)
{
// "package.testname" : First test which matches
for (int i = 0; i < tests.size(); ++i)
{
UnitTest* const test = tests [i];
if (package.equalsIgnoreCase (test->getPackageName ()) &&
testname.equalsIgnoreCase (test->getClassName ()))
{
list.add (test);
break;
}
}
}
else
{
// Get all tests in the package
list = selectPackage (package, tests);
// If no trailing slash on package, try tests
if (list.size () == 0 && indexOfDot == -1)
{
// Try "package" as a testname
list = selectTest (package, tests);
}
}
}
else if (testname != String::empty)
{
list = selectTest (testname, tests);
}
else
{
// All non manual tests
for (int i = 0; i < tests.size(); ++i)
{
UnitTest* const test = tests [i];
if (test->getWhen () != UnitTest::runManual)
list.add (test);
}
}
return list;
}
UnitTests::TestList UnitTests::selectPackage (
String const& package, TestList const& tests) const noexcept
{
TestList list;
list.ensureStorageAllocated (tests.size ());
for (int i = 0; i < tests.size(); ++i)
{
UnitTest* const test = tests [i];
if (package.equalsIgnoreCase (test->getPackageName ()) &&
test->getWhen () != UnitTest::runManual)
list.add (test);
}
return list;
}
UnitTests::TestList UnitTests::selectTest (
String const& testname, TestList const& tests) const noexcept
{
TestList list;
for (int i = 0; i < tests.size(); ++i)
{
UnitTest* const test = tests [i];
if (testname.equalsIgnoreCase (test->getClassName ()))
{
list.add (test);
break;
}
}
return list;
}
UnitTests::TestList UnitTests::selectStartupTests (TestList const& tests) const noexcept
{
TestList list;
for (int i = 0; i < tests.size(); ++i)
{
UnitTest* const test = tests [i];
if (test->getWhen () == UnitTest::runStartup)
list.add (test);
}
return list;
}
void UnitTests::runSelectedTests (String const& match, TestList const& tests, int64 randomSeed)
{
runTests (selectTests (match, tests), randomSeed);
}
void UnitTests::runTests (TestList const& tests, int64 randomSeed)
{
if (randomSeed == 0)
randomSeed = Random().nextInt (0x7fffffff);
m_random = Random (randomSeed);
m_results = new Results;
for (int i = 0; i < tests.size (); ++i)
{
if (shouldAbortTests())
break;
runTest (*tests [i]);
}
m_results->secondsElapsed = RelativeTime (
Time::getCurrentTime () - m_results->whenStarted).inSeconds ();
}
void UnitTests::onFailure ()
{
// A failure occurred and the setting to assert on failures is turned on.
bassert (! m_assertOnFailure);
}
bool UnitTests::shouldAbortTests()
{
return false;
}
void UnitTests::logMessage (const String& message)
{
Logger::writeToLog (message);
}
void UnitTests::logReport (StringArray const& report)
{
for (int i = 0; i < report.size (); ++i)
logMessage (report [i]);
}
void UnitTests::runTest (UnitTest& test)
{
#if 0
try
{
#endif
ScopedPointer <UnitTest::Suite> suite (test.run (this).release ());
m_results->cases += suite->cases.size ();
m_results->tests += suite->tests;
m_results->failures += suite->failures;
m_results->suites.add (suite.release ());
#if 0
}
catch (...)
{
// Should never get here.
Throw (std::runtime_error ("unhandled exception during unit tests"));
}
#endif
}
//------------------------------------------------------------------------------
/** A UnitTest that prints the list of available unit tests.
Not an actual test (it always passes) but if you run it manually it
will print a list of the names of all available unit tests in the program.
*/
class UnitTestsPrinter : public UnitTest
{
public:
UnitTestsPrinter () : UnitTest ("print", "print", runManual)
{
}
void runTest ()
{
beginTestCase ("List available unit tests");
TestList const& list (UnitTest::getAllTests ());
for (int i = 0; i < list.size (); ++i)
{
UnitTest const& test (*list [i]);
String s;
switch (test.getWhen ())
{
default:
case UnitTest::runNormal: s << " "; break;
case UnitTest::runManual: s << "[manual] "; break;
case UnitTest::runStartup: s << "[FORCED] "; break;
};
s << test.getTestName ();
logMessage (s);
}
pass ();
}
};
static UnitTestsPrinter unitTestsPrinter;
} // namespace beast

View File

@@ -1,555 +0,0 @@
//------------------------------------------------------------------------------
/*
This file is part of Beast: https://github.com/vinniefalco/Beast
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
Portions of this file are from JUCE.
Copyright (c) 2013 - Raw Material Software Ltd.
Please visit http://www.juce.com
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
//==============================================================================
#ifndef BEAST_UNITTEST_H_INCLUDED
#define BEAST_UNITTEST_H_INCLUDED
namespace beast
{
class UnitTests;
/** This is a base class for classes that perform a unit test.
To write a test using this class, your code should look something like this:
@code
class MyTest : public UnitTest
{
public:
MyTest() : UnitTest ("Foobar testing", "packageName") { }
void runTest()
{
beginTestCase ("Part 1");
expect (myFoobar.doesSomething());
expect (myFoobar.doesSomethingElse());
beginTestCase ("Part 2");
expect (myOtherFoobar.doesSomething());
expect (myOtherFoobar.doesSomethingElse());
//...
}
};
// This makes the unit test available in the global list
// It doesn't have to be static.
//
static MyTest myTest;
@endcode
To run one or more unit tests, use the UnitTests class.
@see UnitTests
*/
class BEAST_API UnitTest : public Uncopyable
{
public:
/** When the test should be run. */
enum When
{
/** Test will be run when @ref runAllTests is called.
@see runAllTests
*/
runNormal,
/** Test will excluded from @ref runAllTests.
The test can be manually run from @ref runTestsByName.
@see runAllTests, runTestsByName
*/
runManual,
/** Test will be additionlly forced to run on every launch.
If any failures occur, FatalError is called. The tests will
also be run from @ref runAllTests or @ref runTestsByName if
explicitly invoked.
@see FatalError
*/
runStartup
};
/** Describes a single test item.
An item created for each call to the test functions, such as @ref expect
or @expectEquals.
*/
struct Item
{
explicit Item (bool passed_, String failureMessage_ = "")
: passed (passed_)
, failureMessage (failureMessage_)
{
}
bool passed;
String failureMessage;
};
/** Describes a test case.
A test case represents a group of Item objects.
*/
struct Case
{
explicit Case (String const& name_, String const& className_)
: name (name_)
, className (className_)
, whenStarted (Time::getCurrentTime ())
, secondsElapsed (0)
, failures (0)
{
}
String name;
String className;
Time whenStarted;
double secondsElapsed;
int failures;
Array <Item, CriticalSection> items;
};
/** Contains the results of a test.
One of these objects is instantiated each time UnitTest::beginTestCase() is called, and
it contains details of the number of subsequent UnitTest::expect() calls that are
made.
*/
struct Suite
{
String className;
String packageName;
Time whenStarted;
double secondsElapsed;
int tests;
int failures;
OwnedArray <Case, CriticalSection> cases;
//----
Suite (String const& className_, String const& packageName_)
: className (className_)
, packageName (packageName_)
, whenStarted (Time::getCurrentTime ()) // hack for now
, secondsElapsed (0)
, tests (0)
, failures (0)
{
}
// for convenience
String getSuiteName () const noexcept
{
String s;
s << packageName << "::" << className;
return s;
}
};
/** The type of a list of tests. */
typedef Array <UnitTest*, CriticalSection> TestList;
//--------------------------------------------------------------------------
/** Creates a test with the given name, group, and run option.
The group is used when you want to run all tests in a particular group
instead of all tests in general. The run option allows you to write some
tests that are only available manually. For examplem, a performance unit
test that takes a long time which you might not want to run every time
you run all tests.
*/
/*
suiteName: A name
className: The name of the class that the unit test exercises
packageName: A real or pseudo "namespace" describing the general area of
functionality to which the specified class belongs.
Examples: "network", "core", "ui"
A package name can appear in multiple testsuite instances.
*/
explicit UnitTest (String const& name,
String const& group = "",
When when = runNormal);
/** Destructor. */
virtual ~UnitTest();
/** Returns the fully qualified test name in the form <package>.<class> */
String getTestName() const noexcept;
/** Returns the class name of the test. */
const String& getClassName() const noexcept;
/** Returns the package name of the test. */
String const& getPackageName () const noexcept;
/** Returns the run option of the test. */
When getWhen () const noexcept { return m_when; }
/** Returns a Journal that logs to the UnitTests. */
Journal journal () const;
/** Runs the test, using the specified UnitTests.
You shouldn't need to call this method directly - use
UnitTests::runTests() instead.
*/
ScopedPointer <Suite>& run (UnitTests* runner);
/** Returns the set of all UnitTest objects that currently exist. */
static TestList& getAllTests();
//--------------------------------------------------------------------------
/** You can optionally implement this method to set up your test.
This method will be called before runTest().
*/
virtual void initialise();
/** You can optionally implement this method to clear up after your test has been run.
This method will be called after runTest() has returned.
*/
virtual void shutdown();
/** Implement this method in your subclass to actually run your tests.
The content of your implementation should call beginTestCase() and expect()
to perform the tests.
*/
virtual void runTest() = 0;
/** Tells the system that a new subsection of tests is beginning.
This should be called from your runTest() method, and may be called
as many times as you like, to demarcate different sets of tests.
*/
void beginTestCase (String const& name);
// beginTestCase ()
/** Checks that the result of a test is true, and logs this result.
In your runTest() method, you should call this method for each condition that
you want to check, e.g.
@code
void runTest()
{
beginTestCase ("basic tests");
expect (x + y == 2);
expect (getThing() == someThing);
...etc...
}
@endcode
If Suite is true, a pass is logged; if it's false, a failure is logged.
If the failure message is specified, it will be written to the log if the test fails.
Requirements:
Condition must be explicitly convertible to bool
*/
template <class Condition>
bool expect (Condition trueCondition, String const& failureMessage = String::empty)
{
return expect_bool (!!trueCondition, failureMessage);
}
bool expect_bool (bool trueCondition, String const& failureMessage);
/** Checks that the result of a test is false, and logs this result.
This is basically the opposite of expect().
@see expect
Requirements:
Condition must be explicitly convertible to bool
*/
template <class Condition>
bool unexpected (Condition falseCondition, String const& failureMessage = String::empty)
{
return unexpected_bool (!!falseCondition, failureMessage);
}
bool unexpected_bool (bool falseCondition, String const& failureMessage);
/** Compares two values, and if they don't match, prints out a message containing the
expected and actual result values.
*/
template <class ActualType, class ExpectedType>
bool expectEquals (ActualType actual, ExpectedType expected, String failureMessage = String::empty)
{
const bool result = (actual == expected);
if (! result)
{
if (failureMessage.isNotEmpty())
failureMessage << " -- ";
failureMessage << "Expected value: " << expected << ", Actual value: " << actual;
}
return expect (result, failureMessage);
}
/** Causes the test item to pass. */
void pass ();
/** Causes the test item to fail. */
void fail (String const& failureMessage = String::empty);
/** Records an exception in the test item. */
void failException ();
//==============================================================================
/** Writes a message to the test log.
This can only be called during your runTest() method.
*/
void logMessage (const String& message);
void logReport (StringArray const& report);
/** Returns a shared RNG that all unit tests should use. */
Random& random();
private:
void finishCase ();
private:
//==============================================================================
String const m_className;
String const m_packageName;
When const m_when;
UnitTests* m_runner;
ScopedPointer <Suite> m_suite;
ScopedPointer <Case> m_case;
Random m_random;
};
//==============================================================================
/**
Runs a set of unit tests.
You can instantiate one of these objects and use it to invoke tests on a set of
UnitTest objects.
By using a subclass of UnitTests, you can intercept logging messages and
perform custom behaviour when each test completes.
@see UnitTest
*/
class BEAST_API UnitTests : public Uncopyable
{
public:
typedef UnitTest::TestList TestList;
struct Results
{
Results ()
: whenStarted (Time::getCurrentTime ())
, cases (0)
, tests (0)
, failures (0)
{
}
Time whenStarted;
double secondsElapsed;
int cases;
int tests;
int failures;
OwnedArray <UnitTest::Suite> suites;
};
/** */
UnitTests();
/** Destructor. */
virtual ~UnitTests();
/** Sets a flag to indicate whether an assertion should be triggered if a test fails.
This is true by default.
*/
void setAssertOnFailure (bool shouldAssert) noexcept;
/** Retrieve the information on all the suites that were run.
This is overwritten every time new tests are run.
*/
Results const& getResults () const noexcept;
/** Returns `true` if any test failed. */
bool anyTestsFailed () const noexcept;
//--------------------------------------------------------------------------
/** Selects zero or more tests from specified packages or test names.
The name can be in these formats:
""
<package | testname>
<package> "."
<package> "." <testname>
"." <testname>
""
An empty string will match all tests objects which are not
marked to be run manually.
<package | testname>
Selects all tests which belong to that package, excluding those
which must be run manually. If no package with that name exists,
then this will select the first test from any package which matches
the name. If the test is a manual test, it will be selected.
<package> "."
Selects all tests which belong to that package, excluding those
which must be run manually. If no package with that name exists,
then no tests will be selected.
<package> "." <testname>
Selects only the first test that matches the given testname and
package, regardless of the manual run setting. If no test with a
matching package and test name is found, then no test is selected.
"." <testname>
Selects the first test which matches the testname, even if it
is a manual test.
Some examples of names:
"beast" All unit tests in beast
"beast.File" Just the File beast unit test
".Random" The first test with the name Random
@note Matching is not case-sensitive.
@param match The string used to match tests
@param tests An optional parameter containing a list of tests to match.
*/
TestList selectTests (String const& match = "",
TestList const& tests = UnitTest::getAllTests ()) const noexcept;
/** Selects all tests which match the specified package.
Tests marked to be run manually are not included.
@note Matching is not case-sensitive.
@param match The string used to match tests
@param tests An optional parameter containing a list of tests to match.
*/
TestList selectPackage (String const& package,
TestList const& tests = UnitTest::getAllTests ()) const noexcept;
/** Selects the first test whose name matches, from any package.
This can include tests marked to be run manually.
@note Matching is not case-sensitive.
@param match The name of the test to match.
@param tests An optional parameter containing a list of tests to match.
*/
TestList selectTest (String const& testname,
TestList const& tests = UnitTest::getAllTests ()) const noexcept;
/** Selects the startup tests.
A test marked as runStartup will be forced to run on launch.
Typically these are lightweight tests that ensure the system
environment will not cause the program to exhibit undefined behavior.
@param tests An optional parameter containing a list of tests to match.
*/
TestList selectStartupTests (TestList const& tests = UnitTest::getAllTests ()) const noexcept;
/** Run a list of matching tests.
This first calls selectTests and then runTeests on the resulting list.
@param match The string used for matching.
@param tests An optional parameter containing a list of tests to match.
*/
void runSelectedTests (String const& match = "",
TestList const& tests = UnitTest::getAllTests (),
int64 randomSeed = 0);
/** Runs the specified list of tests.
@note The tests are run regardless of the run settings.
@param tests The list of tests to run.
*/
void runTests (TestList const& tests, int64 randomSeed = 0);
Journal journal ()
{
return Journal (m_sink);
}
protected:
friend class UnitTest;
/** Called on a failure. */
void onFailure ();
/** This can be overridden to let the runner know that it should abort the tests
as soon as possible, e.g. because the thread needs to stop.
*/
virtual bool shouldAbortTests ();
/** Logs a message about the current test progress.
By default this just writes the message to the Logger class, but you could override
this to do something else with the data.
*/
virtual void logMessage (String const& message);
/** Logs a report about the current test progress.
This calls logMessage for each String.
*/
virtual void logReport (StringArray const& report);
private:
void runTest (UnitTest& test);
private:
class JournalSink : public Journal::Sink, public Uncopyable
{
public:
explicit JournalSink (UnitTests& tests);
void write (Journal::Severity severity, std::string const& text);
private:
UnitTests& m_tests;
};
bool m_assertOnFailure;
ScopedPointer <Results> m_results;
Random m_random;
JournalSink m_sink;
};
} // namespace beast
#endif

View File

@@ -17,188 +17,8 @@
*/
//==============================================================================
namespace beast
{
namespace beast {
namespace UnitTestUtilities {
namespace UnitTestUtilities
{
JUnitXMLFormatter::JUnitXMLFormatter (UnitTests const& tests)
: m_tests (tests)
, m_currentTime (timeToString (Time::getCurrentTime ()))
, m_hostName (SystemStats::getComputerName ())
{
}
// This is the closest thing to documentation on JUnit XML I could find:
//
// http://junitpdfreport.sourceforge.net/managedcontent/PdfTranslation
//
String JUnitXMLFormatter::createDocumentString ()
{
UnitTests::Results const& results (m_tests.getResults ());
ScopedPointer <XmlElement> testsuites (new XmlElement ("testsuites"));
testsuites->setAttribute ("tests", String (results.tests));
if (results.failures != 0)
testsuites->setAttribute ("failures", String (results.failures));
testsuites->setAttribute ("time", secondsToString (results.secondsElapsed));
for (int i = 0; i < results.suites.size (); ++i)
{
UnitTest::Suite const& suite (*results.suites [i]);
XmlElement* testsuite (new XmlElement ("testsuite"));;
testsuite->setAttribute ("name", suite.className);
testsuite->setAttribute ("tests", String (suite.tests));
if (suite.failures != 0)
testsuite->setAttribute ("failures", String (suite.failures));
testsuite->setAttribute ("time", secondsToString (suite.secondsElapsed));
testsuite->setAttribute ("timestamp", timeToString (suite.whenStarted));
testsuite->setAttribute ("hostname", m_hostName);
testsuite->setAttribute ("package", suite.packageName);
testsuites->addChildElement (testsuite);
for (int i = 0; i < suite.cases.size (); ++i)
{
UnitTest::Case const& testCase (*suite.cases [i]);
XmlElement* testcase (new XmlElement ("testcase"));
testcase->setAttribute ("name", testCase.name);
testcase->setAttribute ("time", secondsToString (testCase.secondsElapsed));
testcase->setAttribute ("classname", suite.className);
testsuite->addChildElement (testcase);
for (int i = 0; i < testCase.items.size (); ++i)
{
UnitTest::Item const& item (testCase.items.getUnchecked (i));
if (!item.passed)
{
XmlElement* failure (new XmlElement ("failure"));
String s;
s << "#" << String (i+1) << " " << item.failureMessage;
failure->setAttribute ("message", s);
testcase->addChildElement (failure);
}
}
}
}
return testsuites->createDocument (
//"https://svn.jenkins-ci.org/trunk/hudson/dtkit/dtkit-format/dtkit-junit-model/src/main/resources/com/thalesgroup/dtkit/junit/model/xsd/junit-4.xsd",
"",
false,
true,
"UTF-8",
999);
};
String JUnitXMLFormatter::timeToString (Time const& time)
{
return time.toString (true, true, false, true);
}
String JUnitXMLFormatter::secondsToString (double seconds)
{
if (seconds < .01)
return String (seconds, 4);
else if (seconds < 1)
return String (seconds, 2);
else if (seconds < 10)
return String (seconds, 1);
else
return String (int (seconds));
}
//------------------------------------------------------------------------------
/** A unit test that always passes.
This can be useful to diagnose continuous integration systems.
*/
class PassUnitTest : public UnitTest
{
public:
PassUnitTest () : UnitTest ("Pass", "beast", runManual)
{
}
void runTest ()
{
beginTestCase ("pass");
pass ();
}
};
static PassUnitTest passUnitTest;
//------------------------------------------------------------------------------
/** A unit test that always fails.
This can be useful to diagnose continuous integration systems.
*/
class FailUnitTest : public UnitTest
{
public:
FailUnitTest () : UnitTest ("Fail", "beast", runManual)
{
}
void runTest ()
{
beginTestCase ("fail");
fail ("Intentional failure");
}
};
static FailUnitTest failUnitTest;
}
//------------------------------------------------------------------------------
class UnitTestUtilitiesTests : public UnitTest
{
public:
UnitTestUtilitiesTests () : UnitTest ("UnitTestUtilities", "beast")
{
}
void testPayload ()
{
using namespace UnitTestUtilities;
int const maxBufferSize = 4000;
int const minimumBytes = 1;
int const numberOfItems = 100;
int64 const seedValue = 50;
beginTestCase ("Payload");
Payload p1 (maxBufferSize);
Payload p2 (maxBufferSize);
for (int i = 0; i < numberOfItems; ++i)
{
p1.repeatableRandomFill (minimumBytes, maxBufferSize, seedValue);
p2.repeatableRandomFill (minimumBytes, maxBufferSize, seedValue);
expect (p1 == p2, "Should be equal");
}
}
void runTest ()
{
testPayload ();
}
};
static UnitTestUtilitiesTests unitTestUtilitiesTests;
} // namespace beast
} // UnitTestUtilities
} // beast

View File

@@ -20,11 +20,8 @@
#ifndef BEAST_UNITTESTUTILITIES_H_INCLUDED
#define BEAST_UNITTESTUTILITIES_H_INCLUDED
namespace beast
{
namespace UnitTestUtilities
{
namespace beast {
namespace UnitTestUtilities {
/** Fairly shuffle an array pseudo-randomly.
*/
@@ -102,39 +99,7 @@ public:
HeapBlock <char> data;
};
//------------------------------------------------------------------------------
/** Format unit test results in JUnit XML format.
The output can be used directly with the Jenkins CI server with
the appropriate JUnit plugin.
JUnit FAQ: http://junit.sourceforge.net/doc/faq/faq.htm
Jenkins Home: http://jenkins-ci.org/
@see UnitTest, UnitTests
*/
class JUnitXMLFormatter : public Uncopyable
{
public:
JUnitXMLFormatter (UnitTests const& tests);
String createDocumentString ();
private:
static String timeToString (Time const& time);
static String secondsToString (double seconds);
private:
UnitTests const& m_tests;
String const m_currentTime;
String const m_hostName;
};
}
} // namespace beast
} // UnitTestUtilities
} // beast
#endif

View File

@@ -21,8 +21,9 @@
*/
//==============================================================================
namespace beast
{
#include "../../../beast/unit_test/suite.h"
namespace beast {
// We need to make a shared singleton or else there are
// issues with the leak detector and order of detruction.
@@ -904,14 +905,19 @@ File File::createTempFile (const String& fileNameEnding)
//==============================================================================
class FileTests : public UnitTest
class File_test : public unit_test::suite
{
public:
FileTests() : UnitTest ("File", "beast") {}
void runTest()
template <class T1, class T2>
bool
expectEquals (T1 const& t1, T2 const& t2)
{
beginTestCase ("Reading");
return expect (t1 == t2);
}
void run()
{
testcase ("Reading");
const File home (File::getSpecialLocation (File::userHomeDirectory));
const File temp (File::getSpecialLocation (File::tempDirectory));
@@ -950,7 +956,7 @@ public:
expect (numRootsExisting > 0);
}
beginTestCase ("Writing");
testcase ("Writing");
File demoFolder (temp.getChildFile ("Beast UnitTests Temp Folder.folder"));
expect (demoFolder.deleteRecursively());
@@ -991,7 +997,7 @@ public:
expect (tempFile.exists());
expect (tempFile.getSize() == 10);
expect (std::abs ((int) (tempFile.getLastModificationTime().toMilliseconds() - Time::getCurrentTime().toMilliseconds())) < 3000);
expectEquals (tempFile.loadFileAsString(), String ("0123456789"));
expect (tempFile.loadFileAsString() == String ("0123456789"));
expect (! demoFolder.containsSubDirectories());
expectEquals (tempFile.getRelativePathFrom (demoFolder.getParentDirectory()), demoFolder.getFileName() + File::separatorString + tempFile.getFileName());
@@ -1036,7 +1042,7 @@ public:
expect (tempFile.getSize() == 10);
}
beginTestCase ("More writing");
testcase ("More writing");
expect (tempFile.appendData ("abcdefghij", 10));
expect (tempFile.getSize() == 20);
@@ -1058,6 +1064,6 @@ public:
}
};
static FileTests fileTests;
BEAST_DEFINE_TESTSUITE (File,beast_core,beast);
} // namespace beast
} // beast

View File

@@ -17,8 +17,9 @@
*/
//==============================================================================
namespace beast
{
#include "../../../beast/unit_test/suite.h"
namespace beast {
RandomAccessFile::RandomAccessFile () noexcept
: fileHandle (nullptr)
@@ -101,13 +102,9 @@ Result RandomAccessFile::flush ()
//------------------------------------------------------------------------------
class RandomAccessFileTests : public UnitTest
class RandomAccessFile_test : public unit_test::suite
{
public:
RandomAccessFileTests () : UnitTest ("RandomAccessFile", "beast")
{
}
enum
{
maxPayload = 8192
@@ -221,7 +218,9 @@ public:
int const seedValue = 50;
beginTestCase (String ("numRecords=") + String (numRecords));
std::stringstream ss;
ss << numRecords << " records";
testcase (ss.str());
// Calculate the path
File const path (File::createTempFile ("RandomAccessFile"));
@@ -264,14 +263,12 @@ public:
}
}
void runTest ()
void run ()
{
testFile (10000);
}
private:
};
static RandomAccessFileTests randomAccessFileTests;
BEAST_DEFINE_TESTSUITE(RandomAccessFile,beast_core,beast);
} // namespace beast
} // beast

Some files were not shown because too many files have changed in this diff Show More