mirror of
https://github.com/boostorg/beast.git
synced 2025-08-04 15:24:31 +02:00
Use unit-test subtree
This commit is contained in:
@@ -1,3 +1,9 @@
|
|||||||
|
Version 123:
|
||||||
|
|
||||||
|
* Use unit-test subtree
|
||||||
|
|
||||||
|
--------------------------------------------------------------------------------
|
||||||
|
|
||||||
Version 122:
|
Version 122:
|
||||||
|
|
||||||
* Add test for issue 807
|
* Add test for issue 807
|
||||||
|
3
Jamfile
3
Jamfile
@@ -67,13 +67,14 @@ variant ubasan
|
|||||||
<define>BOOST_USE_ASAN=1
|
<define>BOOST_USE_ASAN=1
|
||||||
;
|
;
|
||||||
|
|
||||||
path-constant TEST_MAIN : test/extras/include/boost/beast/unit_test/main.cpp ;
|
path-constant TEST_MAIN : subtree/unit_test/include/boost/beast/unit_test/main.cpp ;
|
||||||
|
|
||||||
project /boost/beast
|
project /boost/beast
|
||||||
: requirements
|
: requirements
|
||||||
<implicit-dependency>/boost//headers
|
<implicit-dependency>/boost//headers
|
||||||
<include>.
|
<include>.
|
||||||
<include>./test/extras/include
|
<include>./test/extras/include
|
||||||
|
<include>./subtree/unit_test/include
|
||||||
<library>/boost/system//boost_system
|
<library>/boost/system//boost_system
|
||||||
<library>/boost/coroutine//boost_coroutine
|
<library>/boost/coroutine//boost_coroutine
|
||||||
<library>/boost/filesystem//boost_filesystem
|
<library>/boost/filesystem//boost_filesystem
|
||||||
|
@@ -9,13 +9,16 @@
|
|||||||
|
|
||||||
include_directories (./extern)
|
include_directories (./extern)
|
||||||
include_directories (./extras/include)
|
include_directories (./extras/include)
|
||||||
|
include_directories (../subtree/unit_test/include)
|
||||||
|
|
||||||
file (GLOB_RECURSE EXTRAS_INCLUDES
|
file (GLOB_RECURSE EXTRAS_INCLUDES
|
||||||
${PROJECT_SOURCE_DIR}/test/extras/include/boost/beast/*.hpp
|
${PROJECT_SOURCE_DIR}/test/extras/include/boost/beast/*.hpp
|
||||||
${PROJECT_SOURCE_DIR}/test/extras/include/boost/beast/*.ipp
|
${PROJECT_SOURCE_DIR}/test/extras/include/boost/beast/*.ipp
|
||||||
|
${PROJECT_SOURCE_DIR}/subtree/unit_test/include/beast/*.hpp
|
||||||
|
${PROJECT_SOURCE_DIR}/subtree/unit_test/include/beast/*.ipp
|
||||||
)
|
)
|
||||||
|
|
||||||
set (TEST_MAIN ${PROJECT_SOURCE_DIR}/test/extras/include/boost/beast/unit_test/main.cpp)
|
set (TEST_MAIN ${PROJECT_SOURCE_DIR}/subtree/unit_test/include/boost/beast/unit_test/main.cpp)
|
||||||
|
|
||||||
if (OPENSSL_FOUND)
|
if (OPENSSL_FOUND)
|
||||||
link_libraries (${OPENSSL_LIBRARIES})
|
link_libraries (${OPENSSL_LIBRARIES})
|
||||||
|
@@ -9,6 +9,7 @@
|
|||||||
|
|
||||||
GroupSources(include/boost/beast beast)
|
GroupSources(include/boost/beast beast)
|
||||||
GroupSources(test/extras/include/boost/beast extras)
|
GroupSources(test/extras/include/boost/beast extras)
|
||||||
|
GroupSources(subtree/unit_test/include/boost/beast extras)
|
||||||
GroupSources(test/beast "/")
|
GroupSources(test/beast "/")
|
||||||
|
|
||||||
add_executable (tests-beast
|
add_executable (tests-beast
|
||||||
|
@@ -8,6 +8,7 @@
|
|||||||
#
|
#
|
||||||
|
|
||||||
GroupSources(test/extras/include/boost/beast extras)
|
GroupSources(test/extras/include/boost/beast extras)
|
||||||
|
GroupSources(subtree/unit_test/include/boost/beast extras)
|
||||||
GroupSources(include/boost/beast beast)
|
GroupSources(include/boost/beast beast)
|
||||||
GroupSources(test/beast/core "/")
|
GroupSources(test/beast/core "/")
|
||||||
|
|
||||||
|
@@ -8,6 +8,7 @@
|
|||||||
#
|
#
|
||||||
|
|
||||||
GroupSources(test/extras/include/boost/beast extras)
|
GroupSources(test/extras/include/boost/beast extras)
|
||||||
|
GroupSources(subtree/unit_test/include/boost/beast extras)
|
||||||
GroupSources(include/boost/beast beast)
|
GroupSources(include/boost/beast beast)
|
||||||
GroupSources(test/beast/http "/")
|
GroupSources(test/beast/http "/")
|
||||||
|
|
||||||
|
@@ -8,6 +8,7 @@
|
|||||||
#
|
#
|
||||||
|
|
||||||
GroupSources(test/extras/include/boost/beast extras)
|
GroupSources(test/extras/include/boost/beast extras)
|
||||||
|
GroupSources(subtree/unit_test/include/boost/beast extras)
|
||||||
GroupSources(include/boost/beast beast)
|
GroupSources(include/boost/beast beast)
|
||||||
GroupSources(test/beast/websocket "/")
|
GroupSources(test/beast/websocket "/")
|
||||||
|
|
||||||
|
@@ -9,6 +9,7 @@
|
|||||||
|
|
||||||
GroupSources(include/boost/beast beast)
|
GroupSources(include/boost/beast beast)
|
||||||
GroupSources(test/extras/include/boost/beast extras)
|
GroupSources(test/extras/include/boost/beast extras)
|
||||||
|
GroupSources(subtree/unit_test/include/boost/beast extras)
|
||||||
GroupSources(test/extern/zlib-1.2.11 zlib)
|
GroupSources(test/extern/zlib-1.2.11 zlib)
|
||||||
GroupSources(test/beast/zlib "/")
|
GroupSources(test/beast/zlib "/")
|
||||||
|
|
||||||
|
@@ -8,6 +8,7 @@
|
|||||||
#
|
#
|
||||||
|
|
||||||
GroupSources(test/extras/include/boost/beast extras)
|
GroupSources(test/extras/include/boost/beast extras)
|
||||||
|
GroupSources(subtree/unit_test/include/boost/beast extras)
|
||||||
GroupSources(include/boost/beast beast)
|
GroupSources(include/boost/beast beast)
|
||||||
GroupSources(test/bench/buffers "/")
|
GroupSources(test/bench/buffers "/")
|
||||||
|
|
||||||
|
@@ -8,6 +8,7 @@
|
|||||||
#
|
#
|
||||||
|
|
||||||
GroupSources(test/extras/include/boost/beast extras)
|
GroupSources(test/extras/include/boost/beast extras)
|
||||||
|
GroupSources(subtree/unit_test/include/boost/beast extras)
|
||||||
GroupSources(include/boost/beast beast)
|
GroupSources(include/boost/beast beast)
|
||||||
GroupSources(test/beast/http "/")
|
GroupSources(test/beast/http "/")
|
||||||
GroupSources(test/bench/parser "/")
|
GroupSources(test/bench/parser "/")
|
||||||
|
@@ -8,6 +8,7 @@
|
|||||||
#
|
#
|
||||||
|
|
||||||
GroupSources(test/extras/include/boost/beast extras)
|
GroupSources(test/extras/include/boost/beast extras)
|
||||||
|
GroupSources(subtree/unit_test/include/boost/beast extras)
|
||||||
GroupSources(include/boost/beast beast)
|
GroupSources(include/boost/beast beast)
|
||||||
GroupSources(test/bench/utf8_checker "/")
|
GroupSources(test/bench/utf8_checker "/")
|
||||||
|
|
||||||
|
@@ -10,6 +10,7 @@
|
|||||||
GroupSources(include/boost/beast beast)
|
GroupSources(include/boost/beast beast)
|
||||||
GroupSources(example/common common)
|
GroupSources(example/common common)
|
||||||
GroupSources(test/extras/include/boost/beast extras)
|
GroupSources(test/extras/include/boost/beast extras)
|
||||||
|
GroupSources(subtree/unit_test/include/boost/beast extras)
|
||||||
GroupSources(test/bench/wsload "/")
|
GroupSources(test/bench/wsload "/")
|
||||||
|
|
||||||
add_executable (bench-wsload
|
add_executable (bench-wsload
|
||||||
|
@@ -9,6 +9,7 @@
|
|||||||
|
|
||||||
GroupSources(include/boost/beast beast)
|
GroupSources(include/boost/beast beast)
|
||||||
GroupSources(test/extras/include/boost/beast extras)
|
GroupSources(test/extras/include/boost/beast extras)
|
||||||
|
GroupSources(subtree/unit_test/include/boost/beast extras)
|
||||||
GroupSources(test/extern/zlib-1.2.11 zlib)
|
GroupSources(test/extern/zlib-1.2.11 zlib)
|
||||||
GroupSources(test/bench/zlib "/")
|
GroupSources(test/bench/zlib "/")
|
||||||
|
|
||||||
|
@@ -9,6 +9,7 @@
|
|||||||
|
|
||||||
GroupSources(example example)
|
GroupSources(example example)
|
||||||
GroupSources(test/extras/include/boost/beast extras)
|
GroupSources(test/extras/include/boost/beast extras)
|
||||||
|
GroupSources(subtree/unit_test/include/boost/beast extras)
|
||||||
GroupSources(include/boost/beast beast)
|
GroupSources(include/boost/beast beast)
|
||||||
GroupSources(test/doc "/")
|
GroupSources(test/doc "/")
|
||||||
|
|
||||||
|
@@ -9,6 +9,7 @@
|
|||||||
|
|
||||||
GroupSources(example/common common)
|
GroupSources(example/common common)
|
||||||
GroupSources(test/extras/include/boost/beast extras)
|
GroupSources(test/extras/include/boost/beast extras)
|
||||||
|
GroupSources(subtree/unit_test/include/boost/beast extras)
|
||||||
GroupSources(include/boost/beast beast)
|
GroupSources(include/boost/beast beast)
|
||||||
GroupSources(test/example/common "/")
|
GroupSources(test/example/common "/")
|
||||||
|
|
||||||
|
@@ -1,59 +0,0 @@
|
|||||||
//
|
|
||||||
// Copyright (c) 2016-2017 Vinnie Falco (vinnie dot falco at gmail dot com)
|
|
||||||
//
|
|
||||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
|
||||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
|
||||||
//
|
|
||||||
// Official repository: https://github.com/boostorg/beast
|
|
||||||
//
|
|
||||||
|
|
||||||
#ifndef BOOST_BEAST_UNIT_TEST_AMOUNT_HPP
|
|
||||||
#define BOOST_BEAST_UNIT_TEST_AMOUNT_HPP
|
|
||||||
|
|
||||||
#include <cstddef>
|
|
||||||
#include <ostream>
|
|
||||||
#include <string>
|
|
||||||
|
|
||||||
namespace boost {
|
|
||||||
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;
|
|
||||||
|
|
||||||
template<class = void>
|
|
||||||
amount(std::size_t n, std::string const& what);
|
|
||||||
|
|
||||||
friend
|
|
||||||
std::ostream&
|
|
||||||
operator<<(std::ostream& s, amount const& t);
|
|
||||||
};
|
|
||||||
|
|
||||||
template<class>
|
|
||||||
amount::amount(std::size_t n, std::string const& what)
|
|
||||||
: n_(n)
|
|
||||||
, what_(what)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
inline
|
|
||||||
std::ostream&
|
|
||||||
operator<<(std::ostream& s, amount const& t)
|
|
||||||
{
|
|
||||||
s << t.n_ << " " << t.what_ <<((t.n_ != 1) ? "s" : "");
|
|
||||||
return s;
|
|
||||||
}
|
|
||||||
|
|
||||||
} // unit_test
|
|
||||||
} // beast
|
|
||||||
} // boost
|
|
||||||
|
|
||||||
#endif
|
|
@@ -1,95 +0,0 @@
|
|||||||
//
|
|
||||||
// Copyright (c) 2016-2017 Vinnie Falco (vinnie dot falco at gmail dot com)
|
|
||||||
//
|
|
||||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
|
||||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
|
||||||
//
|
|
||||||
// Official repository: https://github.com/boostorg/beast
|
|
||||||
//
|
|
||||||
|
|
||||||
#ifndef BOOST_BEAST_UNIT_TEST_DETAIL_CONST_CONTAINER_HPP
|
|
||||||
#define BOOST_BEAST_UNIT_TEST_DETAIL_CONST_CONTAINER_HPP
|
|
||||||
|
|
||||||
namespace boost {
|
|
||||||
namespace beast {
|
|
||||||
namespace unit_test {
|
|
||||||
namespace detail {
|
|
||||||
|
|
||||||
/** Adapter to constrain a container interface.
|
|
||||||
The interface allows for limited read only operations. Derived classes
|
|
||||||
provide additional behavior.
|
|
||||||
*/
|
|
||||||
template<class Container>
|
|
||||||
class const_container
|
|
||||||
{
|
|
||||||
private:
|
|
||||||
using cont_type = Container;
|
|
||||||
|
|
||||||
cont_type m_cont;
|
|
||||||
|
|
||||||
protected:
|
|
||||||
cont_type& cont()
|
|
||||||
{
|
|
||||||
return m_cont;
|
|
||||||
}
|
|
||||||
|
|
||||||
cont_type const& cont() const
|
|
||||||
{
|
|
||||||
return m_cont;
|
|
||||||
}
|
|
||||||
|
|
||||||
public:
|
|
||||||
using value_type = typename cont_type::value_type;
|
|
||||||
using size_type = typename cont_type::size_type;
|
|
||||||
using difference_type = typename cont_type::difference_type;
|
|
||||||
using iterator = typename cont_type::const_iterator;
|
|
||||||
using const_iterator = typename cont_type::const_iterator;
|
|
||||||
|
|
||||||
/** Returns `true` if the container is empty. */
|
|
||||||
bool
|
|
||||||
empty() const
|
|
||||||
{
|
|
||||||
return m_cont.empty();
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Returns the number of items in the container. */
|
|
||||||
size_type
|
|
||||||
size() const
|
|
||||||
{
|
|
||||||
return m_cont.size();
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Returns forward iterators for traversal. */
|
|
||||||
/** @{ */
|
|
||||||
const_iterator
|
|
||||||
begin() const
|
|
||||||
{
|
|
||||||
return m_cont.cbegin();
|
|
||||||
}
|
|
||||||
|
|
||||||
const_iterator
|
|
||||||
cbegin() const
|
|
||||||
{
|
|
||||||
return m_cont.cbegin();
|
|
||||||
}
|
|
||||||
|
|
||||||
const_iterator
|
|
||||||
end() const
|
|
||||||
{
|
|
||||||
return m_cont.cend();
|
|
||||||
}
|
|
||||||
|
|
||||||
const_iterator
|
|
||||||
cend() const
|
|
||||||
{
|
|
||||||
return m_cont.cend();
|
|
||||||
}
|
|
||||||
/** @} */
|
|
||||||
};
|
|
||||||
|
|
||||||
} // detail
|
|
||||||
} // unit_test
|
|
||||||
} // beast
|
|
||||||
} // boost
|
|
||||||
|
|
||||||
#endif
|
|
@@ -1,130 +0,0 @@
|
|||||||
//
|
|
||||||
// Copyright (c) 2016-2017 Vinnie Falco (vinnie dot falco at gmail dot com)
|
|
||||||
//
|
|
||||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
|
||||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
|
||||||
//
|
|
||||||
// Official repository: https://github.com/boostorg/beast
|
|
||||||
//
|
|
||||||
|
|
||||||
#ifndef BOOST_BEAST_UNIT_TEST_DSTREAM_HPP
|
|
||||||
#define BOOST_BEAST_UNIT_TEST_DSTREAM_HPP
|
|
||||||
|
|
||||||
#include <boost/config.hpp>
|
|
||||||
#include <ios>
|
|
||||||
#include <memory>
|
|
||||||
#include <ostream>
|
|
||||||
#include <streambuf>
|
|
||||||
#include <string>
|
|
||||||
|
|
||||||
#ifdef BOOST_WINDOWS
|
|
||||||
#include <boost/detail/winapi/basic_types.hpp>
|
|
||||||
#include <boost/detail/winapi/debugapi.hpp>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
namespace boost {
|
|
||||||
namespace beast {
|
|
||||||
namespace unit_test {
|
|
||||||
|
|
||||||
#ifdef BOOST_WINDOWS
|
|
||||||
|
|
||||||
namespace detail {
|
|
||||||
|
|
||||||
template<class CharT, class Traits, class Allocator>
|
|
||||||
class dstream_buf
|
|
||||||
: public std::basic_stringbuf<CharT, Traits, Allocator>
|
|
||||||
{
|
|
||||||
using ostream = std::basic_ostream<CharT, Traits>;
|
|
||||||
|
|
||||||
ostream& os_;
|
|
||||||
bool dbg_;
|
|
||||||
|
|
||||||
template<class T>
|
|
||||||
void write(T const*) = delete;
|
|
||||||
|
|
||||||
void write(char const* s)
|
|
||||||
{
|
|
||||||
if(dbg_)
|
|
||||||
boost::detail::winapi::OutputDebugStringA(s);
|
|
||||||
os_ << s;
|
|
||||||
}
|
|
||||||
|
|
||||||
void write(wchar_t const* s)
|
|
||||||
{
|
|
||||||
if(dbg_)
|
|
||||||
boost::detail::winapi::OutputDebugStringW(s);
|
|
||||||
os_ << s;
|
|
||||||
}
|
|
||||||
|
|
||||||
public:
|
|
||||||
explicit
|
|
||||||
dstream_buf(ostream& os)
|
|
||||||
: os_(os)
|
|
||||||
, dbg_(boost::detail::winapi::IsDebuggerPresent() != 0)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
~dstream_buf()
|
|
||||||
{
|
|
||||||
sync();
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
sync() override
|
|
||||||
{
|
|
||||||
write(this->str().c_str());
|
|
||||||
this->str("");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
} // detail
|
|
||||||
|
|
||||||
/** std::ostream with Visual Studio IDE redirection.
|
|
||||||
|
|
||||||
Instances of this stream wrap a specified `std::ostream`
|
|
||||||
(such as `std::cout` or `std::cerr`). If the IDE debugger
|
|
||||||
is attached when the stream is created, output will be
|
|
||||||
additionally copied to the Visual Studio Output window.
|
|
||||||
*/
|
|
||||||
template<
|
|
||||||
class CharT,
|
|
||||||
class Traits = std::char_traits<CharT>,
|
|
||||||
class Allocator = std::allocator<CharT>
|
|
||||||
>
|
|
||||||
class basic_dstream
|
|
||||||
: public std::basic_ostream<CharT, Traits>
|
|
||||||
{
|
|
||||||
detail::dstream_buf<
|
|
||||||
CharT, Traits, Allocator> buf_;
|
|
||||||
|
|
||||||
public:
|
|
||||||
/** Construct a stream.
|
|
||||||
|
|
||||||
@param os The output stream to wrap.
|
|
||||||
*/
|
|
||||||
explicit
|
|
||||||
basic_dstream(std::ostream& os)
|
|
||||||
: std::basic_ostream<CharT, Traits>(&buf_)
|
|
||||||
, buf_(os)
|
|
||||||
{
|
|
||||||
if(os.flags() & std::ios::unitbuf)
|
|
||||||
std::unitbuf(*this);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
using dstream = basic_dstream<char>;
|
|
||||||
using dwstream = basic_dstream<wchar_t>;
|
|
||||||
|
|
||||||
#else
|
|
||||||
|
|
||||||
using dstream = std::ostream&;
|
|
||||||
using dwstream = std::wostream&;
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
} // unit_test
|
|
||||||
} // beast
|
|
||||||
} // boost
|
|
||||||
|
|
||||||
#endif
|
|
@@ -1,55 +0,0 @@
|
|||||||
//
|
|
||||||
// Copyright (c) 2016-2017 Vinnie Falco (vinnie dot falco at gmail dot com)
|
|
||||||
//
|
|
||||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
|
||||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
|
||||||
//
|
|
||||||
// Official repository: https://github.com/boostorg/beast
|
|
||||||
//
|
|
||||||
|
|
||||||
#ifndef BOOST_BEAST_UNIT_TEST_GLOBAL_SUITES_HPP
|
|
||||||
#define BOOST_BEAST_UNIT_TEST_GLOBAL_SUITES_HPP
|
|
||||||
|
|
||||||
#include <boost/beast/unit_test/suite_list.hpp>
|
|
||||||
|
|
||||||
namespace boost {
|
|
||||||
namespace beast {
|
|
||||||
namespace unit_test {
|
|
||||||
|
|
||||||
namespace detail {
|
|
||||||
|
|
||||||
/// Holds test suites registered during static initialization.
|
|
||||||
inline
|
|
||||||
suite_list&
|
|
||||||
global_suites()
|
|
||||||
{
|
|
||||||
static suite_list s;
|
|
||||||
return s;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<class Suite>
|
|
||||||
struct insert_suite
|
|
||||||
{
|
|
||||||
insert_suite(char const* name, char const* module,
|
|
||||||
char const* library, bool manual)
|
|
||||||
{
|
|
||||||
global_suites().insert<Suite>(
|
|
||||||
name, module, library, manual);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
} // detail
|
|
||||||
|
|
||||||
/// Holds test suites registered during static initialization.
|
|
||||||
inline
|
|
||||||
suite_list const&
|
|
||||||
global_suites()
|
|
||||||
{
|
|
||||||
return detail::global_suites();
|
|
||||||
}
|
|
||||||
|
|
||||||
} // unit_test
|
|
||||||
} // beast
|
|
||||||
} // boost
|
|
||||||
|
|
||||||
#endif
|
|
@@ -1,87 +0,0 @@
|
|||||||
//
|
|
||||||
// Copyright (c) 2016-2017 Vinnie Falco (vinnie dot falco at gmail dot com)
|
|
||||||
//
|
|
||||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
|
||||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
|
||||||
//
|
|
||||||
// Official repository: https://github.com/boostorg/beast
|
|
||||||
//
|
|
||||||
|
|
||||||
#include <boost/beast/unit_test/amount.hpp>
|
|
||||||
#include <boost/beast/unit_test/dstream.hpp>
|
|
||||||
#include <boost/beast/unit_test/global_suites.hpp>
|
|
||||||
#include <boost/beast/unit_test/match.hpp>
|
|
||||||
#include <boost/beast/unit_test/reporter.hpp>
|
|
||||||
#include <boost/beast/unit_test/suite.hpp>
|
|
||||||
#include <boost/config.hpp>
|
|
||||||
#include <cstdlib>
|
|
||||||
#include <iostream>
|
|
||||||
#include <vector>
|
|
||||||
|
|
||||||
#ifdef BOOST_MSVC
|
|
||||||
# ifndef WIN32_LEAN_AND_MEAN // VC_EXTRALEAN
|
|
||||||
# define WIN32_LEAN_AND_MEAN
|
|
||||||
# include <windows.h>
|
|
||||||
# undef WIN32_LEAN_AND_MEAN
|
|
||||||
# else
|
|
||||||
# include <windows.h>
|
|
||||||
# endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Simple main used to produce stand
|
|
||||||
// alone executables that run unit tests.
|
|
||||||
int main(int ac, char const* av[])
|
|
||||||
{
|
|
||||||
using namespace std;
|
|
||||||
using namespace boost::beast::unit_test;
|
|
||||||
|
|
||||||
dstream log(std::cerr);
|
|
||||||
std::unitbuf(log);
|
|
||||||
|
|
||||||
#if BOOST_MSVC
|
|
||||||
{
|
|
||||||
int flags = _CrtSetDbgFlag(_CRTDBG_REPORT_FLAG);
|
|
||||||
flags |= _CRTDBG_LEAK_CHECK_DF;
|
|
||||||
_CrtSetDbgFlag(flags);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if(ac == 2)
|
|
||||||
{
|
|
||||||
std::string const s{av[1]};
|
|
||||||
if(s == "-h" || s == "--help")
|
|
||||||
{
|
|
||||||
log <<
|
|
||||||
"Usage:\n"
|
|
||||||
" " << av[0] << ": { <suite-name>... }" <<
|
|
||||||
std::endl;
|
|
||||||
return EXIT_SUCCESS;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
reporter r(log);
|
|
||||||
bool failed;
|
|
||||||
if(ac > 1)
|
|
||||||
{
|
|
||||||
std::vector<selector> v;
|
|
||||||
v.reserve(ac - 1);
|
|
||||||
for(int i = 1; i < ac; ++i)
|
|
||||||
v.emplace_back(selector::automatch, av[i]);
|
|
||||||
auto pred =
|
|
||||||
[&v](suite_info const& si) mutable
|
|
||||||
{
|
|
||||||
for(auto& p : v)
|
|
||||||
if(p(si))
|
|
||||||
return true;
|
|
||||||
return false;
|
|
||||||
};
|
|
||||||
failed = r.run_each_if(global_suites(), pred);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
failed = r.run_each(global_suites());
|
|
||||||
}
|
|
||||||
if(failed)
|
|
||||||
return EXIT_FAILURE;
|
|
||||||
return EXIT_SUCCESS;
|
|
||||||
}
|
|
@@ -1,177 +0,0 @@
|
|||||||
//
|
|
||||||
// Copyright (c) 2016-2017 Vinnie Falco (vinnie dot falco at gmail dot com)
|
|
||||||
//
|
|
||||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
|
||||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
|
||||||
//
|
|
||||||
// Official repository: https://github.com/boostorg/beast
|
|
||||||
//
|
|
||||||
|
|
||||||
#ifndef BOOST_BEAST_UNIT_TEST_MATCH_HPP
|
|
||||||
#define BOOST_BEAST_UNIT_TEST_MATCH_HPP
|
|
||||||
|
|
||||||
#include <boost/beast/unit_test/suite_info.hpp>
|
|
||||||
#include <string>
|
|
||||||
|
|
||||||
namespace boost {
|
|
||||||
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 mode_;
|
|
||||||
std::string pat_;
|
|
||||||
std::string library_;
|
|
||||||
|
|
||||||
public:
|
|
||||||
template<class = void>
|
|
||||||
explicit
|
|
||||||
selector(mode_t mode, std::string const& pattern = "");
|
|
||||||
|
|
||||||
template<class = void>
|
|
||||||
bool
|
|
||||||
operator()(suite_info const& s);
|
|
||||||
};
|
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
template<class>
|
|
||||||
selector::selector(mode_t mode, std::string const& pattern)
|
|
||||||
: mode_(mode)
|
|
||||||
, pat_(pattern)
|
|
||||||
{
|
|
||||||
if(mode_ == automatch && pattern.empty())
|
|
||||||
mode_ = all;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<class>
|
|
||||||
bool
|
|
||||||
selector::operator()(suite_info const& s)
|
|
||||||
{
|
|
||||||
switch(mode_)
|
|
||||||
{
|
|
||||||
case automatch:
|
|
||||||
// suite or full name
|
|
||||||
if(s.name() == pat_ || s.full_name() == pat_)
|
|
||||||
{
|
|
||||||
mode_ = none;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// check module
|
|
||||||
if(pat_ == s.module())
|
|
||||||
{
|
|
||||||
mode_ = module;
|
|
||||||
library_ = s.library();
|
|
||||||
return ! s.manual();
|
|
||||||
}
|
|
||||||
|
|
||||||
// check library
|
|
||||||
if(pat_ == s.library())
|
|
||||||
{
|
|
||||||
mode_ = library;
|
|
||||||
return ! s.manual();
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
|
|
||||||
case suite:
|
|
||||||
return pat_ == s.name();
|
|
||||||
|
|
||||||
case module:
|
|
||||||
return pat_ == s.module() && ! s.manual();
|
|
||||||
|
|
||||||
case library:
|
|
||||||
return 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
|
|
||||||
} // boost
|
|
||||||
|
|
||||||
#endif
|
|
@@ -1,96 +0,0 @@
|
|||||||
//
|
|
||||||
// Copyright (c) 2016-2017 Vinnie Falco (vinnie dot falco at gmail dot com)
|
|
||||||
//
|
|
||||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
|
||||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
|
||||||
//
|
|
||||||
// Official repository: https://github.com/boostorg/beast
|
|
||||||
//
|
|
||||||
|
|
||||||
#ifndef BOOST_BEAST_UNIT_TEST_RECORDER_HPP
|
|
||||||
#define BOOST_BEAST_UNIT_TEST_RECORDER_HPP
|
|
||||||
|
|
||||||
#include <boost/beast/unit_test/results.hpp>
|
|
||||||
#include <boost/beast/unit_test/runner.hpp>
|
|
||||||
|
|
||||||
namespace boost {
|
|
||||||
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() = default;
|
|
||||||
recorder(recorder const&) = default;
|
|
||||||
recorder& operator=(recorder const&) = default;
|
|
||||||
|
|
||||||
/** 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
|
|
||||||
} // boost
|
|
||||||
|
|
||||||
#endif
|
|
@@ -1,293 +0,0 @@
|
|||||||
//
|
|
||||||
// Copyright (c) 2016-2017 Vinnie Falco (vinnie dot falco at gmail dot com)
|
|
||||||
//
|
|
||||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
|
||||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
|
||||||
//
|
|
||||||
// Official repository: https://github.com/boostorg/beast
|
|
||||||
//
|
|
||||||
|
|
||||||
#ifndef BOOST_BEAST_UNIT_TEST_REPORTER_HPP
|
|
||||||
#define BOOST_BEAST_UNIT_TEST_REPORTER_HPP
|
|
||||||
|
|
||||||
#include <boost/beast/unit_test/amount.hpp>
|
|
||||||
#include <boost/beast/unit_test/recorder.hpp>
|
|
||||||
#include <boost/optional.hpp>
|
|
||||||
#include <algorithm>
|
|
||||||
#include <chrono>
|
|
||||||
#include <functional>
|
|
||||||
#include <iomanip>
|
|
||||||
#include <iostream>
|
|
||||||
#include <sstream>
|
|
||||||
#include <string>
|
|
||||||
#include <utility>
|
|
||||||
|
|
||||||
namespace boost {
|
|
||||||
namespace beast {
|
|
||||||
namespace unit_test {
|
|
||||||
|
|
||||||
namespace detail {
|
|
||||||
|
|
||||||
/** A simple test runner that writes everything to a stream in real time.
|
|
||||||
The totals are output when the object is destroyed.
|
|
||||||
*/
|
|
||||||
template<class = void>
|
|
||||||
class reporter : public runner
|
|
||||||
{
|
|
||||||
private:
|
|
||||||
using clock_type = std::chrono::steady_clock;
|
|
||||||
|
|
||||||
struct case_results
|
|
||||||
{
|
|
||||||
std::string name;
|
|
||||||
std::size_t total = 0;
|
|
||||||
std::size_t failed = 0;
|
|
||||||
|
|
||||||
explicit
|
|
||||||
case_results(std::string name_ = "")
|
|
||||||
: name(std::move(name_))
|
|
||||||
{
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
struct suite_results
|
|
||||||
{
|
|
||||||
std::string name;
|
|
||||||
std::size_t cases = 0;
|
|
||||||
std::size_t total = 0;
|
|
||||||
std::size_t failed = 0;
|
|
||||||
typename clock_type::time_point start = clock_type::now();
|
|
||||||
|
|
||||||
explicit
|
|
||||||
suite_results(std::string name_ = "")
|
|
||||||
: name(std::move(name_))
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
add(case_results const& r);
|
|
||||||
};
|
|
||||||
|
|
||||||
struct results
|
|
||||||
{
|
|
||||||
using run_time = std::pair<std::string,
|
|
||||||
typename clock_type::duration>;
|
|
||||||
|
|
||||||
enum
|
|
||||||
{
|
|
||||||
max_top = 10
|
|
||||||
};
|
|
||||||
|
|
||||||
std::size_t suites = 0;
|
|
||||||
std::size_t cases = 0;
|
|
||||||
std::size_t total = 0;
|
|
||||||
std::size_t failed = 0;
|
|
||||||
std::vector<run_time> top;
|
|
||||||
typename clock_type::time_point start = clock_type::now();
|
|
||||||
|
|
||||||
void
|
|
||||||
add(suite_results const& r);
|
|
||||||
};
|
|
||||||
|
|
||||||
std::ostream& os_;
|
|
||||||
results results_;
|
|
||||||
suite_results suite_results_;
|
|
||||||
case_results case_results_;
|
|
||||||
|
|
||||||
public:
|
|
||||||
reporter(reporter const&) = delete;
|
|
||||||
reporter& operator=(reporter const&) = delete;
|
|
||||||
|
|
||||||
~reporter();
|
|
||||||
|
|
||||||
explicit
|
|
||||||
reporter(std::ostream& os = std::cout);
|
|
||||||
|
|
||||||
private:
|
|
||||||
static
|
|
||||||
std::string
|
|
||||||
fmtdur(typename clock_type::duration const& d);
|
|
||||||
|
|
||||||
virtual
|
|
||||||
void
|
|
||||||
on_suite_begin(suite_info const& info) override;
|
|
||||||
|
|
||||||
virtual
|
|
||||||
void
|
|
||||||
on_suite_end() override;
|
|
||||||
|
|
||||||
virtual
|
|
||||||
void
|
|
||||||
on_case_begin(std::string const& name) override;
|
|
||||||
|
|
||||||
virtual
|
|
||||||
void
|
|
||||||
on_case_end() override;
|
|
||||||
|
|
||||||
virtual
|
|
||||||
void
|
|
||||||
on_pass() override;
|
|
||||||
|
|
||||||
virtual
|
|
||||||
void
|
|
||||||
on_fail(std::string const& reason) override;
|
|
||||||
|
|
||||||
virtual
|
|
||||||
void
|
|
||||||
on_log(std::string const& s) override;
|
|
||||||
};
|
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
template<class _>
|
|
||||||
void
|
|
||||||
reporter<_>::
|
|
||||||
suite_results::add(case_results const& r)
|
|
||||||
{
|
|
||||||
++cases;
|
|
||||||
total += r.total;
|
|
||||||
failed += r.failed;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<class _>
|
|
||||||
void
|
|
||||||
reporter<_>::
|
|
||||||
results::add(suite_results const& r)
|
|
||||||
{
|
|
||||||
++suites;
|
|
||||||
total += r.total;
|
|
||||||
cases += r.cases;
|
|
||||||
failed += r.failed;
|
|
||||||
auto const elapsed = clock_type::now() - r.start;
|
|
||||||
if(elapsed >= std::chrono::seconds{1})
|
|
||||||
{
|
|
||||||
auto const iter = std::lower_bound(top.begin(),
|
|
||||||
top.end(), elapsed,
|
|
||||||
[](run_time const& t1,
|
|
||||||
typename clock_type::duration const& t2)
|
|
||||||
{
|
|
||||||
return t1.second > t2;
|
|
||||||
});
|
|
||||||
if(iter != top.end())
|
|
||||||
{
|
|
||||||
top.emplace(iter, r.name, elapsed);
|
|
||||||
if(top.size() > max_top)
|
|
||||||
top.resize(max_top);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
template<class _>
|
|
||||||
reporter<_>::
|
|
||||||
reporter(std::ostream& os)
|
|
||||||
: os_(os)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
template<class _>
|
|
||||||
reporter<_>::~reporter()
|
|
||||||
{
|
|
||||||
if(results_.top.size() > 0)
|
|
||||||
{
|
|
||||||
os_ << "Longest suite times:\n";
|
|
||||||
for(auto const& i : results_.top)
|
|
||||||
os_ << std::setw(8) <<
|
|
||||||
fmtdur(i.second) << " " << i.first << '\n';
|
|
||||||
}
|
|
||||||
auto const elapsed = clock_type::now() - results_.start;
|
|
||||||
os_ <<
|
|
||||||
fmtdur(elapsed) << ", " <<
|
|
||||||
amount{results_.suites, "suite"} << ", " <<
|
|
||||||
amount{results_.cases, "case"} << ", " <<
|
|
||||||
amount{results_.total, "test"} << " total, " <<
|
|
||||||
amount{results_.failed, "failure"} <<
|
|
||||||
std::endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<class _>
|
|
||||||
std::string
|
|
||||||
reporter<_>::fmtdur(typename clock_type::duration const& d)
|
|
||||||
{
|
|
||||||
using namespace std::chrono;
|
|
||||||
auto const ms = duration_cast<milliseconds>(d);
|
|
||||||
if(ms < seconds{1})
|
|
||||||
return std::to_string(ms.count()) + "ms";
|
|
||||||
std::stringstream ss;
|
|
||||||
ss << std::fixed << std::setprecision(1) <<
|
|
||||||
(ms.count()/1000.) << "s";
|
|
||||||
return ss.str();
|
|
||||||
}
|
|
||||||
|
|
||||||
template<class _>
|
|
||||||
void
|
|
||||||
reporter<_>::
|
|
||||||
on_suite_begin(suite_info const& info)
|
|
||||||
{
|
|
||||||
suite_results_ = suite_results{info.full_name()};
|
|
||||||
}
|
|
||||||
|
|
||||||
template<class _>
|
|
||||||
void
|
|
||||||
reporter<_>::on_suite_end()
|
|
||||||
{
|
|
||||||
results_.add(suite_results_);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<class _>
|
|
||||||
void
|
|
||||||
reporter<_>::
|
|
||||||
on_case_begin(std::string const& name)
|
|
||||||
{
|
|
||||||
case_results_ = case_results(name);
|
|
||||||
os_ << suite_results_.name <<
|
|
||||||
(case_results_.name.empty() ? "" :
|
|
||||||
(" " + case_results_.name)) << std::endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<class _>
|
|
||||||
void
|
|
||||||
reporter<_>::
|
|
||||||
on_case_end()
|
|
||||||
{
|
|
||||||
suite_results_.add(case_results_);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<class _>
|
|
||||||
void
|
|
||||||
reporter<_>::
|
|
||||||
on_pass()
|
|
||||||
{
|
|
||||||
++case_results_.total;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<class _>
|
|
||||||
void
|
|
||||||
reporter<_>::
|
|
||||||
on_fail(std::string const& reason)
|
|
||||||
{
|
|
||||||
++case_results_.failed;
|
|
||||||
++case_results_.total;
|
|
||||||
os_ <<
|
|
||||||
"#" << case_results_.total << " failed" <<
|
|
||||||
(reason.empty() ? "" : ": ") << reason << std::endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<class _>
|
|
||||||
void
|
|
||||||
reporter<_>::
|
|
||||||
on_log(std::string const& s)
|
|
||||||
{
|
|
||||||
os_ << s;
|
|
||||||
}
|
|
||||||
|
|
||||||
} // detail
|
|
||||||
|
|
||||||
using reporter = detail::reporter<>;
|
|
||||||
|
|
||||||
} // unit_test
|
|
||||||
} // beast
|
|
||||||
} // boost
|
|
||||||
|
|
||||||
#endif
|
|
@@ -1,246 +0,0 @@
|
|||||||
//
|
|
||||||
// Copyright (c) 2016-2017 Vinnie Falco (vinnie dot falco at gmail dot com)
|
|
||||||
//
|
|
||||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
|
||||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
|
||||||
//
|
|
||||||
// Official repository: https://github.com/boostorg/beast
|
|
||||||
//
|
|
||||||
|
|
||||||
#ifndef BOOST_BEAST_UNIT_TEST_RESULTS_HPP
|
|
||||||
#define BOOST_BEAST_UNIT_TEST_RESULTS_HPP
|
|
||||||
|
|
||||||
#include <boost/beast/unit_test/detail/const_container.hpp>
|
|
||||||
|
|
||||||
#include <string>
|
|
||||||
#include <vector>
|
|
||||||
|
|
||||||
namespace boost {
|
|
||||||
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 detail::const_container <std::vector <test>>
|
|
||||||
{
|
|
||||||
private:
|
|
||||||
std::size_t failed_;
|
|
||||||
|
|
||||||
public:
|
|
||||||
tests_t()
|
|
||||||
: 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 failed_;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Register a successful test condition. */
|
|
||||||
void
|
|
||||||
pass()
|
|
||||||
{
|
|
||||||
cont().emplace_back(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Register a failed test condition. */
|
|
||||||
void
|
|
||||||
fail(std::string const& reason = "")
|
|
||||||
{
|
|
||||||
++failed_;
|
|
||||||
cont().emplace_back(false, reason);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
class log_t
|
|
||||||
: public detail::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 name_;
|
|
||||||
|
|
||||||
public:
|
|
||||||
explicit case_results(std::string const& name = "")
|
|
||||||
: name_(name)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Returns the name of this testcase. */
|
|
||||||
std::string const&
|
|
||||||
name() const
|
|
||||||
{
|
|
||||||
return 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 detail::const_container <std::vector <case_results>>
|
|
||||||
{
|
|
||||||
private:
|
|
||||||
std::string name_;
|
|
||||||
std::size_t total_ = 0;
|
|
||||||
std::size_t failed_ = 0;
|
|
||||||
|
|
||||||
public:
|
|
||||||
explicit suite_results(std::string const& name = "")
|
|
||||||
: name_(name)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Returns the name of this suite. */
|
|
||||||
std::string const&
|
|
||||||
name() const
|
|
||||||
{
|
|
||||||
return name_;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Returns the total number of test conditions. */
|
|
||||||
std::size_t
|
|
||||||
total() const
|
|
||||||
{
|
|
||||||
return total_;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Returns the number of failures. */
|
|
||||||
std::size_t
|
|
||||||
failed() const
|
|
||||||
{
|
|
||||||
return failed_;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Insert a set of testcase results. */
|
|
||||||
/** @{ */
|
|
||||||
void
|
|
||||||
insert(case_results&& r)
|
|
||||||
{
|
|
||||||
cont().emplace_back(std::move(r));
|
|
||||||
total_ += r.tests.total();
|
|
||||||
failed_ += r.tests.failed();
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
insert(case_results const& r)
|
|
||||||
{
|
|
||||||
cont().push_back(r);
|
|
||||||
total_ += r.tests.total();
|
|
||||||
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 detail::const_container <std::vector <suite_results>>
|
|
||||||
{
|
|
||||||
private:
|
|
||||||
std::size_t m_cases;
|
|
||||||
std::size_t total_;
|
|
||||||
std::size_t failed_;
|
|
||||||
|
|
||||||
public:
|
|
||||||
results()
|
|
||||||
: m_cases(0)
|
|
||||||
, total_(0)
|
|
||||||
, 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 total_;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Returns the number of failures. */
|
|
||||||
std::size_t
|
|
||||||
failed() const
|
|
||||||
{
|
|
||||||
return failed_;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Insert a set of suite results. */
|
|
||||||
/** @{ */
|
|
||||||
void
|
|
||||||
insert(suite_results&& r)
|
|
||||||
{
|
|
||||||
m_cases += r.size();
|
|
||||||
total_ += r.total();
|
|
||||||
failed_ += r.failed();
|
|
||||||
cont().emplace_back(std::move(r));
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
insert(suite_results const& r)
|
|
||||||
{
|
|
||||||
m_cases += r.size();
|
|
||||||
total_ += r.total();
|
|
||||||
failed_ += r.failed();
|
|
||||||
cont().push_back(r);
|
|
||||||
}
|
|
||||||
/** @} */
|
|
||||||
};
|
|
||||||
|
|
||||||
} // unit_test
|
|
||||||
} // beast
|
|
||||||
} // boost
|
|
||||||
|
|
||||||
#endif
|
|
@@ -1,292 +0,0 @@
|
|||||||
//
|
|
||||||
// Copyright (c) 2016-2017 Vinnie Falco (vinnie dot falco at gmail dot com)
|
|
||||||
//
|
|
||||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
|
||||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
|
||||||
//
|
|
||||||
// Official repository: https://github.com/boostorg/beast
|
|
||||||
//
|
|
||||||
|
|
||||||
#ifndef BOOST_BEAST_UNIT_TEST_RUNNER_H_INCLUDED
|
|
||||||
#define BOOST_BEAST_UNIT_TEST_RUNNER_H_INCLUDED
|
|
||||||
|
|
||||||
#include <boost/beast/unit_test/suite_info.hpp>
|
|
||||||
#include <boost/assert.hpp>
|
|
||||||
#include <mutex>
|
|
||||||
#include <ostream>
|
|
||||||
#include <string>
|
|
||||||
|
|
||||||
namespace boost {
|
|
||||||
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
|
|
||||||
{
|
|
||||||
std::string arg_;
|
|
||||||
bool default_ = false;
|
|
||||||
bool failed_ = false;
|
|
||||||
bool cond_ = false;
|
|
||||||
std::recursive_mutex mutex_;
|
|
||||||
|
|
||||||
public:
|
|
||||||
runner() = default;
|
|
||||||
virtual ~runner() = default;
|
|
||||||
runner(runner const&) = delete;
|
|
||||||
runner& operator=(runner const&) = delete;
|
|
||||||
|
|
||||||
/** Set the argument string.
|
|
||||||
|
|
||||||
The argument string is available to suites and
|
|
||||||
allows for customization of the test. Each suite
|
|
||||||
defines its own syntax for the argumnet string.
|
|
||||||
The same argument is passed to all suites.
|
|
||||||
*/
|
|
||||||
void
|
|
||||||
arg(std::string const& s)
|
|
||||||
{
|
|
||||||
arg_ = s;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Returns the argument string. */
|
|
||||||
std::string const&
|
|
||||||
arg() const
|
|
||||||
{
|
|
||||||
return arg_;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Run the specified suite.
|
|
||||||
@return `true` if any conditions failed.
|
|
||||||
*/
|
|
||||||
template<class = void>
|
|
||||||
bool
|
|
||||||
run(suite_info const& s);
|
|
||||||
|
|
||||||
/** 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);
|
|
||||||
|
|
||||||
/** 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{});
|
|
||||||
|
|
||||||
/** Run all suites in a container.
|
|
||||||
@return `true` if any conditions failed.
|
|
||||||
*/
|
|
||||||
template<class SequenceContainer>
|
|
||||||
bool
|
|
||||||
run_each(SequenceContainer const& c);
|
|
||||||
|
|
||||||
/** 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{});
|
|
||||||
|
|
||||||
protected:
|
|
||||||
/// 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;
|
|
||||||
|
|
||||||
// Start a new testcase.
|
|
||||||
template<class = void>
|
|
||||||
void
|
|
||||||
testcase(std::string const& name);
|
|
||||||
|
|
||||||
template<class = void>
|
|
||||||
void
|
|
||||||
pass();
|
|
||||||
|
|
||||||
template<class = void>
|
|
||||||
void
|
|
||||||
fail(std::string const& reason);
|
|
||||||
|
|
||||||
template<class = void>
|
|
||||||
void
|
|
||||||
log(std::string const& s);
|
|
||||||
};
|
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
template<class>
|
|
||||||
bool
|
|
||||||
runner::run(suite_info const& s)
|
|
||||||
{
|
|
||||||
// Enable 'default' testcase
|
|
||||||
default_ = true;
|
|
||||||
failed_ = false;
|
|
||||||
on_suite_begin(s);
|
|
||||||
s.run(*this);
|
|
||||||
// Forgot to call pass or fail.
|
|
||||||
BOOST_ASSERT(cond_);
|
|
||||||
on_case_end();
|
|
||||||
on_suite_end();
|
|
||||||
return failed_;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<class FwdIter>
|
|
||||||
bool
|
|
||||||
runner::run(FwdIter first, FwdIter last)
|
|
||||||
{
|
|
||||||
bool failed(false);
|
|
||||||
for(;first != last; ++first)
|
|
||||||
failed = run(*first) || failed;
|
|
||||||
return failed;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<class FwdIter, class Pred>
|
|
||||||
bool
|
|
||||||
runner::run_if(FwdIter first, FwdIter last, Pred pred)
|
|
||||||
{
|
|
||||||
bool failed(false);
|
|
||||||
for(;first != last; ++first)
|
|
||||||
if(pred(*first))
|
|
||||||
failed = run(*first) || failed;
|
|
||||||
return failed;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<class SequenceContainer>
|
|
||||||
bool
|
|
||||||
runner::run_each(SequenceContainer const& c)
|
|
||||||
{
|
|
||||||
bool failed(false);
|
|
||||||
for(auto const& s : c)
|
|
||||||
failed = run(s) || failed;
|
|
||||||
return failed;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<class SequenceContainer, class Pred>
|
|
||||||
bool
|
|
||||||
runner::run_each_if(SequenceContainer const& c, Pred pred)
|
|
||||||
{
|
|
||||||
bool failed(false);
|
|
||||||
for(auto const& s : c)
|
|
||||||
if(pred(s))
|
|
||||||
failed = run(s) || failed;
|
|
||||||
return failed;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<class>
|
|
||||||
void
|
|
||||||
runner::testcase(std::string const& name)
|
|
||||||
{
|
|
||||||
std::lock_guard<std::recursive_mutex> lock(mutex_);
|
|
||||||
// Name may not be empty
|
|
||||||
BOOST_ASSERT(default_ || ! name.empty());
|
|
||||||
// Forgot to call pass or fail
|
|
||||||
BOOST_ASSERT(default_ || cond_);
|
|
||||||
if(! default_)
|
|
||||||
on_case_end();
|
|
||||||
default_ = false;
|
|
||||||
cond_ = false;
|
|
||||||
on_case_begin(name);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<class>
|
|
||||||
void
|
|
||||||
runner::pass()
|
|
||||||
{
|
|
||||||
std::lock_guard<std::recursive_mutex> lock(mutex_);
|
|
||||||
if(default_)
|
|
||||||
testcase("");
|
|
||||||
on_pass();
|
|
||||||
cond_ = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<class>
|
|
||||||
void
|
|
||||||
runner::fail(std::string const& reason)
|
|
||||||
{
|
|
||||||
std::lock_guard<std::recursive_mutex> lock(mutex_);
|
|
||||||
if(default_)
|
|
||||||
testcase("");
|
|
||||||
on_fail(reason);
|
|
||||||
failed_ = true;
|
|
||||||
cond_ = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<class>
|
|
||||||
void
|
|
||||||
runner::log(std::string const& s)
|
|
||||||
{
|
|
||||||
std::lock_guard<std::recursive_mutex> lock(mutex_);
|
|
||||||
if(default_)
|
|
||||||
testcase("");
|
|
||||||
on_log(s);
|
|
||||||
}
|
|
||||||
|
|
||||||
} // unit_test
|
|
||||||
} // beast
|
|
||||||
} // boost
|
|
||||||
|
|
||||||
#endif
|
|
@@ -1,690 +0,0 @@
|
|||||||
//
|
|
||||||
// Copyright (c) 2016-2017 Vinnie Falco (vinnie dot falco at gmail dot com)
|
|
||||||
//
|
|
||||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
|
||||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
|
||||||
//
|
|
||||||
// Official repository: https://github.com/boostorg/beast
|
|
||||||
//
|
|
||||||
|
|
||||||
#ifndef BOOST_BEAST_UNIT_TEST_SUITE_HPP
|
|
||||||
#define BOOST_BEAST_UNIT_TEST_SUITE_HPP
|
|
||||||
|
|
||||||
#include <boost/beast/unit_test/runner.hpp>
|
|
||||||
#include <boost/filesystem.hpp>
|
|
||||||
#include <boost/throw_exception.hpp>
|
|
||||||
#include <ostream>
|
|
||||||
#include <sstream>
|
|
||||||
#include <string>
|
|
||||||
|
|
||||||
namespace boost {
|
|
||||||
namespace beast {
|
|
||||||
namespace unit_test {
|
|
||||||
|
|
||||||
namespace detail {
|
|
||||||
|
|
||||||
template<class String>
|
|
||||||
static
|
|
||||||
std::string
|
|
||||||
make_reason(String const& reason,
|
|
||||||
char const* file, int line)
|
|
||||||
{
|
|
||||||
std::string s(reason);
|
|
||||||
if(! s.empty())
|
|
||||||
s.append(": ");
|
|
||||||
namespace fs = boost::filesystem;
|
|
||||||
s.append(fs::path{file}.filename().string());
|
|
||||||
s.append("(");
|
|
||||||
s.append(std::to_string(line));
|
|
||||||
s.append(")");
|
|
||||||
return s;
|
|
||||||
}
|
|
||||||
|
|
||||||
} // detail
|
|
||||||
|
|
||||||
class thread;
|
|
||||||
|
|
||||||
enum abort_t
|
|
||||||
{
|
|
||||||
no_abort_on_fail,
|
|
||||||
abort_on_fail
|
|
||||||
};
|
|
||||||
|
|
||||||
/** 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 BOOST_BEAST_DEFINE_UNIT_TEST macro in a
|
|
||||||
translation unit.
|
|
||||||
*/
|
|
||||||
class suite
|
|
||||||
{
|
|
||||||
private:
|
|
||||||
bool abort_ = false;
|
|
||||||
bool aborted_ = false;
|
|
||||||
runner* runner_ = nullptr;
|
|
||||||
|
|
||||||
// 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 "test suite aborted";
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template<class CharT, class Traits, class Allocator>
|
|
||||||
class log_buf
|
|
||||||
: public std::basic_stringbuf<CharT, Traits, Allocator>
|
|
||||||
{
|
|
||||||
suite& suite_;
|
|
||||||
|
|
||||||
public:
|
|
||||||
explicit
|
|
||||||
log_buf(suite& self)
|
|
||||||
: suite_(self)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
~log_buf()
|
|
||||||
{
|
|
||||||
sync();
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
sync() override
|
|
||||||
{
|
|
||||||
auto const& s = this->str();
|
|
||||||
if(s.size() > 0)
|
|
||||||
suite_.runner_->log(s);
|
|
||||||
this->str("");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template<
|
|
||||||
class CharT,
|
|
||||||
class Traits = std::char_traits<CharT>,
|
|
||||||
class Allocator = std::allocator<CharT>
|
|
||||||
>
|
|
||||||
class log_os : public std::basic_ostream<CharT, Traits>
|
|
||||||
{
|
|
||||||
log_buf<CharT, Traits, Allocator> buf_;
|
|
||||||
|
|
||||||
public:
|
|
||||||
explicit
|
|
||||||
log_os(suite& self)
|
|
||||||
: std::basic_ostream<CharT, Traits>(&buf_)
|
|
||||||
, buf_(self)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
class scoped_testcase;
|
|
||||||
|
|
||||||
class testcase_t
|
|
||||||
{
|
|
||||||
suite& suite_;
|
|
||||||
std::stringstream ss_;
|
|
||||||
|
|
||||||
public:
|
|
||||||
explicit
|
|
||||||
testcase_t(suite& self)
|
|
||||||
: suite_(self)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
/** 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 Determines if suite continues running after a failure.
|
|
||||||
*/
|
|
||||||
void
|
|
||||||
operator()(std::string const& name,
|
|
||||||
abort_t abort = no_abort_on_fail);
|
|
||||||
|
|
||||||
scoped_testcase
|
|
||||||
operator()(abort_t abort);
|
|
||||||
|
|
||||||
template<class T>
|
|
||||||
scoped_testcase
|
|
||||||
operator<<(T const& t);
|
|
||||||
};
|
|
||||||
|
|
||||||
public:
|
|
||||||
/** Logging output stream.
|
|
||||||
|
|
||||||
Text sent to the log output stream will be forwarded to
|
|
||||||
the output stream associated with the runner.
|
|
||||||
*/
|
|
||||||
log_os<char> log;
|
|
||||||
|
|
||||||
/** Memberspace for declaring test cases. */
|
|
||||||
testcase_t testcase;
|
|
||||||
|
|
||||||
/** Returns the "current" running suite.
|
|
||||||
If no suite is running, nullptr is returned.
|
|
||||||
*/
|
|
||||||
static
|
|
||||||
suite*
|
|
||||||
this_suite()
|
|
||||||
{
|
|
||||||
return *p_this_suite();
|
|
||||||
}
|
|
||||||
|
|
||||||
suite()
|
|
||||||
: log(*this)
|
|
||||||
, testcase(*this)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
/** 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.
|
|
||||||
*/
|
|
||||||
template<class = void>
|
|
||||||
void
|
|
||||||
operator()(runner& r);
|
|
||||||
|
|
||||||
/** Record a successful test condition. */
|
|
||||||
template<class = void>
|
|
||||||
void
|
|
||||||
pass();
|
|
||||||
|
|
||||||
/** Record a failure.
|
|
||||||
|
|
||||||
@param reason Optional text added to the output on a failure.
|
|
||||||
|
|
||||||
@param file The source code file where the test failed.
|
|
||||||
|
|
||||||
@param line The source code line number where the test failed.
|
|
||||||
*/
|
|
||||||
/** @{ */
|
|
||||||
template<class String>
|
|
||||||
void
|
|
||||||
fail(String const& reason, char const* file, int line);
|
|
||||||
|
|
||||||
template<class = void>
|
|
||||||
void
|
|
||||||
fail(std::string const& reason = "");
|
|
||||||
/** @} */
|
|
||||||
|
|
||||||
/** Evaluate a test condition.
|
|
||||||
|
|
||||||
This function provides improved logging by incorporating the
|
|
||||||
file name and line number into the reported output on failure,
|
|
||||||
as well as additional text specified by the caller.
|
|
||||||
|
|
||||||
@param shouldBeTrue The condition to test. The condition
|
|
||||||
is evaluated in a boolean context.
|
|
||||||
|
|
||||||
@param reason Optional added text to output on a failure.
|
|
||||||
|
|
||||||
@param file The source code file where the test failed.
|
|
||||||
|
|
||||||
@param line The source code line number where the test failed.
|
|
||||||
|
|
||||||
@return `true` if the test condition indicates success.
|
|
||||||
*/
|
|
||||||
/** @{ */
|
|
||||||
template<class Condition>
|
|
||||||
bool
|
|
||||||
expect(Condition const& shouldBeTrue)
|
|
||||||
{
|
|
||||||
return expect(shouldBeTrue, "");
|
|
||||||
}
|
|
||||||
|
|
||||||
template<class Condition, class String>
|
|
||||||
bool
|
|
||||||
expect(Condition const& shouldBeTrue, String const& reason);
|
|
||||||
|
|
||||||
template<class Condition>
|
|
||||||
bool
|
|
||||||
expect(Condition const& shouldBeTrue,
|
|
||||||
char const* file, int line)
|
|
||||||
{
|
|
||||||
return expect(shouldBeTrue, "", file, line);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<class Condition, class String>
|
|
||||||
bool
|
|
||||||
expect(Condition const& shouldBeTrue,
|
|
||||||
String const& reason, char const* file, int line);
|
|
||||||
/** @} */
|
|
||||||
|
|
||||||
//
|
|
||||||
// DEPRECATED
|
|
||||||
//
|
|
||||||
// Expect an exception from f()
|
|
||||||
template<class F, class String>
|
|
||||||
bool
|
|
||||||
except(F&& f, String const& reason);
|
|
||||||
template<class F>
|
|
||||||
bool
|
|
||||||
except(F&& f)
|
|
||||||
{
|
|
||||||
return except(f, "");
|
|
||||||
}
|
|
||||||
template<class E, class F, class String>
|
|
||||||
bool
|
|
||||||
except(F&& f, String const& reason);
|
|
||||||
template<class E, class F>
|
|
||||||
bool
|
|
||||||
except(F&& f)
|
|
||||||
{
|
|
||||||
return except<E>(f, "");
|
|
||||||
}
|
|
||||||
template<class F, class String>
|
|
||||||
bool
|
|
||||||
unexcept(F&& f, String const& reason);
|
|
||||||
template<class F>
|
|
||||||
bool
|
|
||||||
unexcept(F&& f)
|
|
||||||
{
|
|
||||||
return unexcept(f, "");
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Return the argument associated with the runner. */
|
|
||||||
std::string const&
|
|
||||||
arg() const
|
|
||||||
{
|
|
||||||
return runner_->arg();
|
|
||||||
}
|
|
||||||
|
|
||||||
// DEPRECATED
|
|
||||||
// @return `true` if the test condition indicates success(a false value)
|
|
||||||
template<class Condition, class String>
|
|
||||||
bool
|
|
||||||
unexpected(Condition shouldBeFalse,
|
|
||||||
String const& reason);
|
|
||||||
|
|
||||||
template<class Condition>
|
|
||||||
bool
|
|
||||||
unexpected(Condition shouldBeFalse)
|
|
||||||
{
|
|
||||||
return unexpected(shouldBeFalse, "");
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
friend class thread;
|
|
||||||
|
|
||||||
static
|
|
||||||
suite**
|
|
||||||
p_this_suite()
|
|
||||||
{
|
|
||||||
static suite* pts = nullptr;
|
|
||||||
return &pts;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Runs the suite. */
|
|
||||||
virtual
|
|
||||||
void
|
|
||||||
run() = 0;
|
|
||||||
|
|
||||||
void
|
|
||||||
propagate_abort();
|
|
||||||
|
|
||||||
template<class = void>
|
|
||||||
void
|
|
||||||
run(runner& r);
|
|
||||||
};
|
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
// Helper for streaming testcase names
|
|
||||||
class suite::scoped_testcase
|
|
||||||
{
|
|
||||||
private:
|
|
||||||
suite& suite_;
|
|
||||||
std::stringstream& ss_;
|
|
||||||
|
|
||||||
public:
|
|
||||||
scoped_testcase& operator=(scoped_testcase const&) = delete;
|
|
||||||
|
|
||||||
~scoped_testcase()
|
|
||||||
{
|
|
||||||
auto const& name = ss_.str();
|
|
||||||
if(! name.empty())
|
|
||||||
suite_.runner_->testcase(name);
|
|
||||||
}
|
|
||||||
|
|
||||||
scoped_testcase(suite& self, std::stringstream& ss)
|
|
||||||
: suite_(self)
|
|
||||||
, ss_(ss)
|
|
||||||
{
|
|
||||||
ss_.clear();
|
|
||||||
ss_.str({});
|
|
||||||
}
|
|
||||||
|
|
||||||
template<class T>
|
|
||||||
scoped_testcase(suite& self,
|
|
||||||
std::stringstream& ss, T const& t)
|
|
||||||
: suite_(self)
|
|
||||||
, ss_(ss)
|
|
||||||
{
|
|
||||||
ss_.clear();
|
|
||||||
ss_.str({});
|
|
||||||
ss_ << t;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<class T>
|
|
||||||
scoped_testcase&
|
|
||||||
operator<<(T const& t)
|
|
||||||
{
|
|
||||||
ss_ << t;
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
inline
|
|
||||||
void
|
|
||||||
suite::testcase_t::operator()(
|
|
||||||
std::string const& name, abort_t abort)
|
|
||||||
{
|
|
||||||
suite_.abort_ = abort == abort_on_fail;
|
|
||||||
suite_.runner_->testcase(name);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline
|
|
||||||
suite::scoped_testcase
|
|
||||||
suite::testcase_t::operator()(abort_t abort)
|
|
||||||
{
|
|
||||||
suite_.abort_ = abort == abort_on_fail;
|
|
||||||
return { suite_, ss_ };
|
|
||||||
}
|
|
||||||
|
|
||||||
template<class T>
|
|
||||||
inline
|
|
||||||
suite::scoped_testcase
|
|
||||||
suite::testcase_t::operator<<(T const& t)
|
|
||||||
{
|
|
||||||
return { suite_, ss_, t };
|
|
||||||
}
|
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
template<class>
|
|
||||||
void
|
|
||||||
suite::
|
|
||||||
operator()(runner& r)
|
|
||||||
{
|
|
||||||
*p_this_suite() = this;
|
|
||||||
try
|
|
||||||
{
|
|
||||||
run(r);
|
|
||||||
*p_this_suite() = nullptr;
|
|
||||||
}
|
|
||||||
catch(...)
|
|
||||||
{
|
|
||||||
*p_this_suite() = nullptr;
|
|
||||||
throw;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
template<class Condition, class String>
|
|
||||||
bool
|
|
||||||
suite::
|
|
||||||
expect(
|
|
||||||
Condition const& shouldBeTrue, String const& reason)
|
|
||||||
{
|
|
||||||
if(shouldBeTrue)
|
|
||||||
{
|
|
||||||
pass();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
fail(reason);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<class Condition, class String>
|
|
||||||
bool
|
|
||||||
suite::
|
|
||||||
expect(Condition const& shouldBeTrue,
|
|
||||||
String const& reason, char const* file, int line)
|
|
||||||
{
|
|
||||||
if(shouldBeTrue)
|
|
||||||
{
|
|
||||||
pass();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
fail(detail::make_reason(reason, file, line));
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// DEPRECATED
|
|
||||||
|
|
||||||
template<class F, class String>
|
|
||||||
bool
|
|
||||||
suite::
|
|
||||||
except(F&& f, String const& reason)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
f();
|
|
||||||
fail(reason);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
catch(...)
|
|
||||||
{
|
|
||||||
pass();
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<class E, class F, class String>
|
|
||||||
bool
|
|
||||||
suite::
|
|
||||||
except(F&& f, String const& reason)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
f();
|
|
||||||
fail(reason);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
catch(E const&)
|
|
||||||
{
|
|
||||||
pass();
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<class F, class String>
|
|
||||||
bool
|
|
||||||
suite::
|
|
||||||
unexcept(F&& f, String const& reason)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
f();
|
|
||||||
pass();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
catch(...)
|
|
||||||
{
|
|
||||||
fail(reason);
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<class Condition, class String>
|
|
||||||
bool
|
|
||||||
suite::
|
|
||||||
unexpected(
|
|
||||||
Condition shouldBeFalse, String const& reason)
|
|
||||||
{
|
|
||||||
bool const b =
|
|
||||||
static_cast<bool>(shouldBeFalse);
|
|
||||||
if(! b)
|
|
||||||
pass();
|
|
||||||
else
|
|
||||||
fail(reason);
|
|
||||||
return ! b;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<class>
|
|
||||||
void
|
|
||||||
suite::
|
|
||||||
pass()
|
|
||||||
{
|
|
||||||
propagate_abort();
|
|
||||||
runner_->pass();
|
|
||||||
}
|
|
||||||
|
|
||||||
// ::fail
|
|
||||||
template<class>
|
|
||||||
void
|
|
||||||
suite::
|
|
||||||
fail(std::string const& reason)
|
|
||||||
{
|
|
||||||
propagate_abort();
|
|
||||||
runner_->fail(reason);
|
|
||||||
if(abort_)
|
|
||||||
{
|
|
||||||
aborted_ = true;
|
|
||||||
BOOST_THROW_EXCEPTION(abort_exception());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
template<class String>
|
|
||||||
void
|
|
||||||
suite::
|
|
||||||
fail(String const& reason, char const* file, int line)
|
|
||||||
{
|
|
||||||
fail(detail::make_reason(reason, file, line));
|
|
||||||
}
|
|
||||||
|
|
||||||
inline
|
|
||||||
void
|
|
||||||
suite::
|
|
||||||
propagate_abort()
|
|
||||||
{
|
|
||||||
if(abort_ && aborted_)
|
|
||||||
BOOST_THROW_EXCEPTION(abort_exception());
|
|
||||||
}
|
|
||||||
|
|
||||||
template<class>
|
|
||||||
void
|
|
||||||
suite::
|
|
||||||
run(runner& r)
|
|
||||||
{
|
|
||||||
runner_ = &r;
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
run();
|
|
||||||
}
|
|
||||||
catch(abort_exception const&)
|
|
||||||
{
|
|
||||||
// ends the suite
|
|
||||||
}
|
|
||||||
catch(std::exception const& e)
|
|
||||||
{
|
|
||||||
runner_->fail("unhandled exception: " +
|
|
||||||
std::string(e.what()));
|
|
||||||
}
|
|
||||||
catch(...)
|
|
||||||
{
|
|
||||||
runner_->fail("unhandled exception");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifndef BEAST_EXPECT
|
|
||||||
/** Check a precondition.
|
|
||||||
|
|
||||||
If the condition is false, the file and line number are reported.
|
|
||||||
*/
|
|
||||||
#define BEAST_EXPECT(cond) expect(cond, __FILE__, __LINE__)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef BEAST_EXPECTS
|
|
||||||
/** Check a precondition.
|
|
||||||
|
|
||||||
If the condition is false, the file and line number are reported.
|
|
||||||
*/
|
|
||||||
#define BEAST_EXPECTS(cond, reason) ((cond) ? (pass(), true) : \
|
|
||||||
(fail((reason), __FILE__, __LINE__), false))
|
|
||||||
#endif
|
|
||||||
|
|
||||||
} // unit_test
|
|
||||||
} // beast
|
|
||||||
} // boost
|
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
// detail:
|
|
||||||
// This inserts the suite with the given manual flag
|
|
||||||
#define BEAST_DEFINE_TESTSUITE_INSERT(Library,Module,Class,manual) \
|
|
||||||
static beast::unit_test::detail::insert_suite <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.
|
|
||||||
|
|
||||||
Library Identifies the library.
|
|
||||||
Module Identifies the module.
|
|
||||||
Class The type representing the class being tested.
|
|
||||||
|
|
||||||
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 <boost/beast/unit_test/global_suites.hpp>
|
|
||||||
#define BEAST_DEFINE_TESTSUITE(Library,Module,Class) \
|
|
||||||
BEAST_DEFINE_TESTSUITE_INSERT(Library,Module,Class,false)
|
|
||||||
#define BEAST_DEFINE_TESTSUITE_MANUAL(Library,Module,Class) \
|
|
||||||
BEAST_DEFINE_TESTSUITE_INSERT(Library,Module,Class,true)
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
#endif
|
|
@@ -1,126 +0,0 @@
|
|||||||
//
|
|
||||||
// Copyright (c) 2016-2017 Vinnie Falco (vinnie dot falco at gmail dot com)
|
|
||||||
//
|
|
||||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
|
||||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
|
||||||
//
|
|
||||||
// Official repository: https://github.com/boostorg/beast
|
|
||||||
//
|
|
||||||
|
|
||||||
#ifndef BOOST_BEAST_UNIT_TEST_SUITE_INFO_HPP
|
|
||||||
#define BOOST_BEAST_UNIT_TEST_SUITE_INFO_HPP
|
|
||||||
|
|
||||||
#include <cstring>
|
|
||||||
#include <functional>
|
|
||||||
#include <string>
|
|
||||||
#include <utility>
|
|
||||||
|
|
||||||
namespace boost {
|
|
||||||
namespace beast {
|
|
||||||
namespace unit_test {
|
|
||||||
|
|
||||||
class runner;
|
|
||||||
|
|
||||||
/** Associates a unit test type with metadata. */
|
|
||||||
class suite_info
|
|
||||||
{
|
|
||||||
using run_type = std::function<void(runner&)>;
|
|
||||||
|
|
||||||
std::string name_;
|
|
||||||
std::string module_;
|
|
||||||
std::string library_;
|
|
||||||
bool manual_;
|
|
||||||
run_type run_;
|
|
||||||
|
|
||||||
public:
|
|
||||||
suite_info(
|
|
||||||
std::string name,
|
|
||||||
std::string module,
|
|
||||||
std::string library,
|
|
||||||
bool manual,
|
|
||||||
run_type run)
|
|
||||||
: name_(std::move(name))
|
|
||||||
, module_(std::move(module))
|
|
||||||
, library_(std::move(library))
|
|
||||||
, manual_(manual)
|
|
||||||
, run_(std::move(run))
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string const&
|
|
||||||
name() const
|
|
||||||
{
|
|
||||||
return name_;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string const&
|
|
||||||
module() const
|
|
||||||
{
|
|
||||||
return module_;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string const&
|
|
||||||
library() const
|
|
||||||
{
|
|
||||||
return library_;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Returns `true` if this suite only runs manually.
|
|
||||||
bool
|
|
||||||
manual() const
|
|
||||||
{
|
|
||||||
return manual_;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Return the canonical suite name as a string.
|
|
||||||
std::string
|
|
||||||
full_name() const
|
|
||||||
{
|
|
||||||
return library_ + "." + module_ + "." + name_;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Run a new instance of the associated test suite.
|
|
||||||
void
|
|
||||||
run(runner& r) const
|
|
||||||
{
|
|
||||||
run_(r);
|
|
||||||
}
|
|
||||||
|
|
||||||
friend
|
|
||||||
bool
|
|
||||||
operator<(suite_info const& lhs, suite_info const& rhs)
|
|
||||||
{
|
|
||||||
return
|
|
||||||
std::tie(lhs.library_, lhs.module_, lhs.name_) <
|
|
||||||
std::tie(rhs.library_, rhs.module_, rhs.name_);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
/// Convenience for producing suite_info for a given test type.
|
|
||||||
template<class Suite>
|
|
||||||
suite_info
|
|
||||||
make_suite_info(
|
|
||||||
std::string name,
|
|
||||||
std::string module,
|
|
||||||
std::string library,
|
|
||||||
bool manual)
|
|
||||||
{
|
|
||||||
return suite_info(
|
|
||||||
std::move(name),
|
|
||||||
std::move(module),
|
|
||||||
std::move(library),
|
|
||||||
manual,
|
|
||||||
[](runner& r)
|
|
||||||
{
|
|
||||||
Suite{}(r);
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
} // unit_test
|
|
||||||
} // beast
|
|
||||||
} // boost
|
|
||||||
|
|
||||||
#endif
|
|
@@ -1,81 +0,0 @@
|
|||||||
//
|
|
||||||
// Copyright (c) 2016-2017 Vinnie Falco (vinnie dot falco at gmail dot com)
|
|
||||||
//
|
|
||||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
|
||||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
|
||||||
//
|
|
||||||
// Official repository: https://github.com/boostorg/beast
|
|
||||||
//
|
|
||||||
|
|
||||||
#ifndef BOOST_BEAST_UNIT_TEST_SUITE_LIST_HPP
|
|
||||||
#define BOOST_BEAST_UNIT_TEST_SUITE_LIST_HPP
|
|
||||||
|
|
||||||
#include <boost/beast/unit_test/suite_info.hpp>
|
|
||||||
#include <boost/beast/unit_test/detail/const_container.hpp>
|
|
||||||
#include <boost/assert.hpp>
|
|
||||||
#include <typeindex>
|
|
||||||
#include <set>
|
|
||||||
#include <unordered_set>
|
|
||||||
|
|
||||||
namespace boost {
|
|
||||||
namespace beast {
|
|
||||||
namespace unit_test {
|
|
||||||
|
|
||||||
/// A container of test suites.
|
|
||||||
class suite_list
|
|
||||||
: public detail::const_container <std::set <suite_info>>
|
|
||||||
{
|
|
||||||
private:
|
|
||||||
#ifndef NDEBUG
|
|
||||||
std::unordered_set<std::string> names_;
|
|
||||||
std::unordered_set<std::type_index> 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);
|
|
||||||
};
|
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
template<class Suite>
|
|
||||||
void
|
|
||||||
suite_list::insert(
|
|
||||||
char const* name,
|
|
||||||
char const* module,
|
|
||||||
char const* library,
|
|
||||||
bool manual)
|
|
||||||
{
|
|
||||||
#ifndef NDEBUG
|
|
||||||
{
|
|
||||||
std::string s;
|
|
||||||
s = std::string(library) + "." + module + "." + name;
|
|
||||||
auto const result(names_.insert(s));
|
|
||||||
BOOST_ASSERT(result.second); // Duplicate name
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
auto const result(classes_.insert(
|
|
||||||
std::type_index(typeid(Suite))));
|
|
||||||
BOOST_ASSERT(result.second); // Duplicate type
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
cont().emplace(make_suite_info<Suite>(
|
|
||||||
name, module, library, manual));
|
|
||||||
}
|
|
||||||
|
|
||||||
} // unit_test
|
|
||||||
} // beast
|
|
||||||
} // boost
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
@@ -1,128 +0,0 @@
|
|||||||
//
|
|
||||||
// Copyright (c) 2016-2017 Vinnie Falco (vinnie dot falco at gmail dot com)
|
|
||||||
//
|
|
||||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
|
||||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
|
||||||
//
|
|
||||||
// Official repository: https://github.com/boostorg/beast
|
|
||||||
//
|
|
||||||
|
|
||||||
#ifndef BOOST_BEAST_UNIT_TEST_THREAD_HPP
|
|
||||||
#define BOOST_BEAST_UNIT_TEST_THREAD_HPP
|
|
||||||
|
|
||||||
#include <boost/beast/unit_test/suite.hpp>
|
|
||||||
#include <functional>
|
|
||||||
#include <thread>
|
|
||||||
#include <utility>
|
|
||||||
|
|
||||||
namespace boost {
|
|
||||||
namespace beast {
|
|
||||||
namespace unit_test {
|
|
||||||
|
|
||||||
/** Replacement for std::thread that handles exceptions in unit tests. */
|
|
||||||
class thread
|
|
||||||
{
|
|
||||||
private:
|
|
||||||
suite* s_ = nullptr;
|
|
||||||
std::thread t_;
|
|
||||||
|
|
||||||
public:
|
|
||||||
using id = std::thread::id;
|
|
||||||
using native_handle_type = std::thread::native_handle_type;
|
|
||||||
|
|
||||||
thread() = default;
|
|
||||||
thread(thread const&) = delete;
|
|
||||||
thread& operator=(thread const&) = delete;
|
|
||||||
|
|
||||||
thread(thread&& other)
|
|
||||||
: s_(other.s_)
|
|
||||||
, t_(std::move(other.t_))
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
thread& operator=(thread&& other)
|
|
||||||
{
|
|
||||||
s_ = other.s_;
|
|
||||||
t_ = std::move(other.t_);
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<class F, class... Args>
|
|
||||||
explicit
|
|
||||||
thread(suite& s, F&& f, Args&&... args)
|
|
||||||
: s_(&s)
|
|
||||||
{
|
|
||||||
std::function<void(void)> b =
|
|
||||||
std::bind(std::forward<F>(f),
|
|
||||||
std::forward<Args>(args)...);
|
|
||||||
t_ = std::thread(&thread::run, this,
|
|
||||||
std::move(b));
|
|
||||||
}
|
|
||||||
|
|
||||||
bool
|
|
||||||
joinable() const
|
|
||||||
{
|
|
||||||
return t_.joinable();
|
|
||||||
}
|
|
||||||
|
|
||||||
std::thread::id
|
|
||||||
get_id() const
|
|
||||||
{
|
|
||||||
return t_.get_id();
|
|
||||||
}
|
|
||||||
|
|
||||||
static
|
|
||||||
unsigned
|
|
||||||
hardware_concurrency() noexcept
|
|
||||||
{
|
|
||||||
return std::thread::hardware_concurrency();
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
join()
|
|
||||||
{
|
|
||||||
t_.join();
|
|
||||||
s_->propagate_abort();
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
detach()
|
|
||||||
{
|
|
||||||
t_.detach();
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
swap(thread& other)
|
|
||||||
{
|
|
||||||
std::swap(s_, other.s_);
|
|
||||||
std::swap(t_, other.t_);
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
void
|
|
||||||
run(std::function <void(void)> f)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
f();
|
|
||||||
}
|
|
||||||
catch(suite::abort_exception const&)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
catch(std::exception const& e)
|
|
||||||
{
|
|
||||||
s_->fail("unhandled exception: " +
|
|
||||||
std::string(e.what()));
|
|
||||||
}
|
|
||||||
catch(...)
|
|
||||||
{
|
|
||||||
s_->fail("unhandled exception");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
} // unit_test
|
|
||||||
} // beast
|
|
||||||
} // boost
|
|
||||||
|
|
||||||
#endif
|
|
Reference in New Issue
Block a user