mirror of
https://github.com/boostorg/url.git
synced 2025-05-10 01:43:52 +00:00
refactor test framework files
This commit is contained in:
parent
35982f4d47
commit
daf605409a
File diff suppressed because it is too large
Load Diff
@ -9,23 +9,572 @@
|
||||
|
||||
#include "test_suite.hpp"
|
||||
|
||||
#include <algorithm>
|
||||
#include <atomic>
|
||||
#include <chrono>
|
||||
#include <cstring>
|
||||
#include <iomanip>
|
||||
#include <iostream>
|
||||
#include <ostream>
|
||||
#include <vector>
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <windows.h>
|
||||
#include <debugapi.h>
|
||||
#include <crtdbg.h>
|
||||
#include <sstream>
|
||||
#endif
|
||||
|
||||
namespace test_suite {
|
||||
|
||||
//----------------------------------------------------------
|
||||
//
|
||||
// debug_stream
|
||||
//
|
||||
//----------------------------------------------------------
|
||||
|
||||
#ifdef _MSC_VER
|
||||
|
||||
namespace detail {
|
||||
|
||||
class debug_streambuf
|
||||
: public std::stringbuf
|
||||
{
|
||||
std::ostream& os_;
|
||||
bool dbg_;
|
||||
|
||||
void
|
||||
write(char const* s)
|
||||
{
|
||||
if(dbg_)
|
||||
::OutputDebugStringA(s);
|
||||
os_ << s;
|
||||
}
|
||||
|
||||
public:
|
||||
explicit
|
||||
debug_streambuf(
|
||||
std::ostream& os)
|
||||
: os_(os)
|
||||
, dbg_(::IsDebuggerPresent() != 0)
|
||||
{
|
||||
}
|
||||
|
||||
~debug_streambuf()
|
||||
{
|
||||
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
|
||||
`ostream` (such as `cout` or `cerr`). If a
|
||||
debugger is attached when the stream is
|
||||
created, output will additionally copied
|
||||
to the debugger's output window.
|
||||
*/
|
||||
class debug_stream : public std::ostream
|
||||
{
|
||||
detail::debug_streambuf buf_;
|
||||
|
||||
public:
|
||||
/** Construct a stream.
|
||||
|
||||
@param os The output stream to wrap.
|
||||
*/
|
||||
explicit
|
||||
debug_stream(
|
||||
std::ostream& os)
|
||||
: std::ostream(&buf_)
|
||||
, buf_(os)
|
||||
{
|
||||
if(os.flags() & std::ios::unitbuf)
|
||||
std::unitbuf(*this);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
#else
|
||||
|
||||
using debug_stream = std::ostream&;
|
||||
|
||||
#endif
|
||||
|
||||
//----------------------------------------------------------
|
||||
//
|
||||
// suite
|
||||
//
|
||||
//----------------------------------------------------------
|
||||
|
||||
any_suite::
|
||||
~any_suite() = default;
|
||||
|
||||
//----------------------------------------------------------
|
||||
|
||||
suites&
|
||||
suites::
|
||||
instance() noexcept
|
||||
{
|
||||
class suites_impl : public suites
|
||||
{
|
||||
std::vector<any_suite const*> v_;
|
||||
|
||||
public:
|
||||
void
|
||||
insert(any_suite const& t) override
|
||||
{
|
||||
v_.push_back(&t);
|
||||
}
|
||||
|
||||
iterator
|
||||
begin() const noexcept override
|
||||
{
|
||||
if(! v_.empty())
|
||||
return &v_[0];
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
iterator
|
||||
end() const noexcept override
|
||||
{
|
||||
if(! v_.empty())
|
||||
return &v_[0] + v_.size();
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void
|
||||
sort() override
|
||||
{
|
||||
std::sort(
|
||||
v_.begin(),
|
||||
v_.end(),
|
||||
[]( any_suite const* p0,
|
||||
any_suite const* p1)
|
||||
{
|
||||
auto s0 = p0->name();
|
||||
auto n0 = std::strlen(s0);
|
||||
auto s1 = p1->name();
|
||||
auto n1 = std::strlen(s1);
|
||||
return std::lexicographical_compare(
|
||||
s0, s0 + n0, s1, s1 + n1);
|
||||
});
|
||||
}
|
||||
};
|
||||
static suites_impl impl;
|
||||
return impl;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------
|
||||
//
|
||||
// runner
|
||||
//
|
||||
//----------------------------------------------------------
|
||||
|
||||
any_runner*&
|
||||
any_runner::
|
||||
instance_impl() noexcept
|
||||
{
|
||||
static any_runner* p = nullptr;
|
||||
return p;
|
||||
}
|
||||
|
||||
any_runner&
|
||||
any_runner::
|
||||
instance() noexcept
|
||||
{
|
||||
return *instance_impl();
|
||||
}
|
||||
|
||||
any_runner::
|
||||
any_runner() noexcept
|
||||
: prev_(instance_impl())
|
||||
{
|
||||
instance_impl() = this;
|
||||
}
|
||||
|
||||
any_runner::
|
||||
~any_runner()
|
||||
{
|
||||
instance_impl() = prev_;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------
|
||||
//
|
||||
// implementation
|
||||
//
|
||||
//----------------------------------------------------------
|
||||
|
||||
namespace detail {
|
||||
|
||||
bool
|
||||
test_impl(
|
||||
bool cond,
|
||||
char const* expr,
|
||||
char const* func,
|
||||
char const* file,
|
||||
int line)
|
||||
{
|
||||
return any_runner::instance().test(
|
||||
cond, expr, func, file, line);
|
||||
}
|
||||
|
||||
void
|
||||
throw_failed_impl(
|
||||
const char* expr,
|
||||
char const* excep,
|
||||
char const* func,
|
||||
char const* file,
|
||||
int line)
|
||||
{
|
||||
std::stringstream ss;
|
||||
ss <<
|
||||
"expression '" << expr <<
|
||||
"' didn't throw '" << excep <<
|
||||
"' in function '" << func <<
|
||||
"'";
|
||||
any_runner::instance().test(false, ss.str().c_str(),
|
||||
func, file, line);
|
||||
}
|
||||
|
||||
void
|
||||
no_throw_failed_impl(
|
||||
const char* expr,
|
||||
char const* excep,
|
||||
char const* func,
|
||||
char const* file,
|
||||
int line)
|
||||
{
|
||||
std::stringstream ss;
|
||||
ss <<
|
||||
"expression '" << expr <<
|
||||
"' threw '" << excep <<
|
||||
"' in function '" << func <<
|
||||
"'";
|
||||
any_runner::instance().test(false, ss.str().c_str(),
|
||||
func, file, line);
|
||||
}
|
||||
|
||||
void
|
||||
no_throw_failed_impl(
|
||||
const char* expr,
|
||||
char const* func,
|
||||
char const* file,
|
||||
int line)
|
||||
{
|
||||
std::stringstream ss;
|
||||
ss <<
|
||||
"expression '" << expr <<
|
||||
"' threw in function '" << func << "'";
|
||||
any_runner::instance().test(false, ss.str().c_str(),
|
||||
func, file, line);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------
|
||||
//
|
||||
// simple_runner
|
||||
//
|
||||
//----------------------------------------------------------
|
||||
|
||||
using clock_type =
|
||||
std::chrono::steady_clock;
|
||||
|
||||
struct elapsed
|
||||
{
|
||||
clock_type::duration d;
|
||||
};
|
||||
|
||||
std::ostream&
|
||||
operator<<(
|
||||
std::ostream& os,
|
||||
elapsed const& e)
|
||||
{
|
||||
using namespace std::chrono;
|
||||
auto const ms = duration_cast<
|
||||
milliseconds>(e.d);
|
||||
if(ms < seconds{1})
|
||||
{
|
||||
os << ms.count() << "ms";
|
||||
}
|
||||
else
|
||||
{
|
||||
std::streamsize width{
|
||||
os.width()};
|
||||
std::streamsize precision{
|
||||
os.precision()};
|
||||
os << std::fixed <<
|
||||
std::setprecision(1) <<
|
||||
(ms.count() / 1000.0) << "s";
|
||||
os.precision(precision);
|
||||
os.width(width);
|
||||
}
|
||||
return os;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------
|
||||
//
|
||||
// log_type
|
||||
//
|
||||
//----------------------------------------------------------
|
||||
|
||||
std::ostream&
|
||||
detail::
|
||||
log_type::
|
||||
stream() noexcept
|
||||
{
|
||||
struct buffer : std::stringbuf
|
||||
{
|
||||
int
|
||||
sync() override
|
||||
{
|
||||
auto const& s = this->str();
|
||||
if(s.size() > 0)
|
||||
any_runner::instance().note(s.c_str());
|
||||
this->str("");
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
|
||||
struct ostream : std::ostream
|
||||
{
|
||||
buffer buf_;
|
||||
|
||||
ostream()
|
||||
: std::ostream(&buf_)
|
||||
{
|
||||
}
|
||||
|
||||
~ostream()
|
||||
{
|
||||
buf_.sync();
|
||||
}
|
||||
};
|
||||
|
||||
static ostream ss;
|
||||
return ss;
|
||||
}
|
||||
|
||||
} // detail
|
||||
} // test_suite
|
||||
|
||||
//------------------------------------------------
|
||||
|
||||
namespace test_suite {
|
||||
namespace detail {
|
||||
|
||||
class simple_runner : public any_runner
|
||||
{
|
||||
struct summary
|
||||
{
|
||||
char const* name;
|
||||
clock_type::time_point start;
|
||||
clock_type::duration elapsed;
|
||||
std::atomic<std::size_t> failed;
|
||||
std::atomic<std::size_t> total;
|
||||
|
||||
summary(summary const& other) noexcept
|
||||
: name(other.name)
|
||||
, start(other.start)
|
||||
, elapsed(other.elapsed)
|
||||
, failed(other.failed.load())
|
||||
, total(other.total.load())
|
||||
{
|
||||
}
|
||||
|
||||
explicit
|
||||
summary(char const* name_) noexcept
|
||||
: name(name_)
|
||||
, start(clock_type::now())
|
||||
, failed(0)
|
||||
, total(0)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
summary all_;
|
||||
std::ostream& log_;
|
||||
std::vector<summary> v_;
|
||||
|
||||
public:
|
||||
explicit
|
||||
simple_runner(
|
||||
std::ostream& os)
|
||||
: all_("(all)")
|
||||
, log_(os)
|
||||
{
|
||||
std::unitbuf(log_);
|
||||
v_.reserve(256);
|
||||
}
|
||||
|
||||
~simple_runner()
|
||||
{
|
||||
log_ <<
|
||||
elapsed{clock_type::now() -
|
||||
all_.start } << ", " <<
|
||||
v_.size() << " suites, " <<
|
||||
all_.failed.load() << " failures, " <<
|
||||
all_.total.load() << " total." <<
|
||||
std::endl;
|
||||
}
|
||||
|
||||
// true if no failures
|
||||
bool
|
||||
success() const noexcept
|
||||
{
|
||||
return all_.failed.load() == 0;
|
||||
}
|
||||
|
||||
void
|
||||
run(any_suite const& test) override
|
||||
{
|
||||
v_.emplace_back(test.name());
|
||||
log_ << test.name() << "\n";
|
||||
test.run();
|
||||
v_.back().elapsed =
|
||||
clock_type::now() -
|
||||
v_.back().start;
|
||||
}
|
||||
|
||||
void
|
||||
note(char const* msg) override
|
||||
{
|
||||
log_ << msg << "\n";
|
||||
}
|
||||
|
||||
char const*
|
||||
filename(
|
||||
char const* file)
|
||||
{
|
||||
auto const p0 = file;
|
||||
auto p = p0 + std::strlen(file);
|
||||
while(p-- != p0)
|
||||
{
|
||||
#ifdef _MSC_VER
|
||||
if(*p == '\\')
|
||||
#else
|
||||
if(*p == '/')
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
return p + 1;
|
||||
}
|
||||
|
||||
bool test(bool, char const*, char const*, char const*, int) override;
|
||||
};
|
||||
|
||||
//----------------------------------------------------------
|
||||
|
||||
bool
|
||||
simple_runner::
|
||||
test(
|
||||
bool cond,
|
||||
char const* expr,
|
||||
char const* func,
|
||||
char const* file,
|
||||
int line)
|
||||
{
|
||||
auto const id = ++all_.total;
|
||||
++v_.back().total;
|
||||
if(cond)
|
||||
return true;
|
||||
++all_.failed;
|
||||
++v_.back().failed;
|
||||
(void)func;
|
||||
log_ <<
|
||||
"#" << id << " " <<
|
||||
filename(file) << "(" << line << ") "
|
||||
"failed: '" << expr << "'"
|
||||
//" in " << func <<
|
||||
"\n";
|
||||
log_.flush();
|
||||
return false;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------
|
||||
|
||||
int
|
||||
run(std::ostream& out,
|
||||
int argc, char const* const* argv)
|
||||
{
|
||||
if(argc == 2)
|
||||
{
|
||||
std::string arg(argv[1]);
|
||||
if(arg == "-h" || arg == "--help")
|
||||
{
|
||||
log <<
|
||||
"Usage:\n"
|
||||
" " << argv[0] << ": { <suite-name>... }" <<
|
||||
std::endl;
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
}
|
||||
|
||||
simple_runner any_runner(out);
|
||||
suites::instance().sort();
|
||||
if(argc == 1)
|
||||
{
|
||||
for(any_suite const* sp :
|
||||
suites::instance())
|
||||
any_runner.run(*sp);
|
||||
}
|
||||
else
|
||||
{
|
||||
std::vector<std::string> args;
|
||||
args.reserve(argc - 1);
|
||||
for(int i = 0; i < argc - 1; ++i)
|
||||
args.push_back(argv[i + 1]);
|
||||
for(auto const& e : suites::instance())
|
||||
{
|
||||
std::string s(e->name());
|
||||
if(std::find_if(
|
||||
args.begin(), args.end(),
|
||||
[&](std::string const& arg)
|
||||
{
|
||||
if(arg.size() > s.size())
|
||||
return false;
|
||||
return s.compare(
|
||||
s.size() - arg.size(),
|
||||
arg.size(),
|
||||
arg.data(),
|
||||
arg.size()) == 0;
|
||||
}) != args.end())
|
||||
{
|
||||
any_runner.run(*e);
|
||||
}
|
||||
}
|
||||
}
|
||||
return any_runner.success() ?
|
||||
EXIT_SUCCESS : EXIT_FAILURE;
|
||||
}
|
||||
|
||||
} // detail
|
||||
} // test_suite
|
||||
|
||||
//------------------------------------------------
|
||||
|
||||
// Simple main used to produce stand
|
||||
// alone executables that run unit tests.
|
||||
int main(int argc, char const* const* argv)
|
||||
{
|
||||
#ifdef _MSC_VER
|
||||
{
|
||||
int flags = _CrtSetDbgFlag(_CRTDBG_REPORT_FLAG);
|
||||
flags |= _CRTDBG_LEAK_CHECK_DF;
|
||||
_CrtSetDbgFlag(flags);
|
||||
}
|
||||
int flags = _CrtSetDbgFlag(
|
||||
_CRTDBG_REPORT_FLAG);
|
||||
flags |= _CRTDBG_LEAK_CHECK_DF;
|
||||
_CrtSetDbgFlag(flags);
|
||||
#endif
|
||||
|
||||
::test_suite::debug_stream log(std::cerr);
|
||||
return ::test_suite::run(log, argc, argv);
|
||||
return ::test_suite::detail::run(log, argc, argv);
|
||||
}
|
||||
|
514
extra/test_suite.hpp
Normal file
514
extra/test_suite.hpp
Normal file
@ -0,0 +1,514 @@
|
||||
//
|
||||
// Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.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/CPPAlliance/url
|
||||
//
|
||||
|
||||
#ifndef BOOST_URL_EXTRA_TEST_SUITE_HPP
|
||||
#define BOOST_URL_EXTRA_TEST_SUITE_HPP
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/current_function.hpp>
|
||||
#include <cctype>
|
||||
#include <sstream>
|
||||
#include <type_traits>
|
||||
|
||||
// This is a derivative work
|
||||
// Copyright 2002-2018 Peter Dimov
|
||||
// Copyright (c) 2002, 2009, 2014 Peter Dimov
|
||||
// Copyright (2) Beman Dawes 2010, 2011
|
||||
// Copyright (3) Ion Gaztanaga 2013
|
||||
//
|
||||
// Copyright 2018 Glen Joseph Fernandes
|
||||
// (glenjofe@gmail.com)
|
||||
|
||||
namespace test_suite {
|
||||
|
||||
//------------------------------------------------
|
||||
|
||||
struct any_suite
|
||||
{
|
||||
virtual ~any_suite() = 0;
|
||||
virtual char const* name() const noexcept = 0;
|
||||
virtual void run() const = 0;
|
||||
};
|
||||
|
||||
//------------------------------------------------
|
||||
|
||||
struct suites
|
||||
{
|
||||
using iterator = any_suite const* const*;
|
||||
virtual void insert(any_suite const&) = 0;
|
||||
virtual iterator begin() const noexcept = 0;
|
||||
virtual iterator end() const noexcept = 0;
|
||||
|
||||
// DEPRECATED
|
||||
virtual void sort() = 0;
|
||||
|
||||
static suites& instance() noexcept;
|
||||
};
|
||||
|
||||
//------------------------------------------------
|
||||
|
||||
template<class T>
|
||||
class suite : public any_suite
|
||||
{
|
||||
char const* name_;
|
||||
|
||||
public:
|
||||
explicit
|
||||
suite(char const* name) noexcept
|
||||
: name_(name)
|
||||
{
|
||||
suites::instance().insert(*this);
|
||||
}
|
||||
|
||||
char const*
|
||||
name() const noexcept override
|
||||
{
|
||||
return name_;
|
||||
}
|
||||
|
||||
void
|
||||
run() const override
|
||||
{
|
||||
T().run();
|
||||
}
|
||||
};
|
||||
|
||||
//------------------------------------------------
|
||||
|
||||
class any_runner
|
||||
{
|
||||
any_runner* prev_;
|
||||
|
||||
static any_runner*&
|
||||
instance_impl() noexcept;
|
||||
|
||||
public:
|
||||
static any_runner& instance() noexcept;
|
||||
|
||||
any_runner() noexcept;
|
||||
~any_runner();
|
||||
|
||||
virtual void run(any_suite const& test) = 0;
|
||||
virtual void note(char const* msg) = 0;
|
||||
virtual bool test(bool cond,
|
||||
char const* expr, char const* func,
|
||||
char const* file, int line) = 0;
|
||||
};
|
||||
|
||||
//------------------------------------------------
|
||||
|
||||
namespace detail {
|
||||
|
||||
// In the comparisons below, it is possible that
|
||||
// T and U are signed and unsigned integer types,
|
||||
// which generates warnings in some compilers.
|
||||
// A cleaner fix would require common_type trait
|
||||
// or some meta-programming, which would introduce
|
||||
// a dependency on Boost.TypeTraits. To avoid
|
||||
// the dependency we just disable the warnings.
|
||||
#if defined(__clang__) && defined(__has_warning)
|
||||
# if __has_warning("-Wsign-compare")
|
||||
# pragma clang diagnostic push
|
||||
# pragma clang diagnostic ignored "-Wsign-compare"
|
||||
# endif
|
||||
#elif defined(_MSC_VER)
|
||||
# pragma warning(push)
|
||||
# pragma warning(disable: 4389)
|
||||
#elif defined(__GNUC__) && !(defined(__INTEL_COMPILER) || defined(__ICL) || defined(__ICC) || defined(__ECC)) && (__GNUC__ * 100 + __GNUC_MINOR__) >= 406
|
||||
# pragma GCC diagnostic push
|
||||
# pragma GCC diagnostic ignored "-Wsign-compare"
|
||||
#endif
|
||||
|
||||
template<class...>
|
||||
struct make_void
|
||||
{
|
||||
using type = void;
|
||||
};
|
||||
|
||||
template<class... Ts>
|
||||
using void_t = typename make_void<Ts...>::type;
|
||||
|
||||
template <class T, class = void>
|
||||
struct is_streamable : std::false_type
|
||||
{};
|
||||
|
||||
template <class T>
|
||||
struct is_streamable<
|
||||
T, void_t<decltype(std::declval<
|
||||
std::ostream&>() << std::declval<T&>())
|
||||
> > : std::true_type
|
||||
{};
|
||||
|
||||
template <class T>
|
||||
auto
|
||||
test_output_impl(T const& v) ->
|
||||
typename std::enable_if<
|
||||
is_streamable<T>::value,
|
||||
T const&>::type
|
||||
{
|
||||
return v;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
auto
|
||||
test_output_impl(T const&) ->
|
||||
typename std::enable_if<
|
||||
! is_streamable<T>::value,
|
||||
std::string>::type
|
||||
{
|
||||
return "?";
|
||||
}
|
||||
|
||||
// specialize test output for char pointers to avoid printing as cstring
|
||||
template<class T>
|
||||
const void* test_output_impl(T volatile* v) { return const_cast<T*>(v); }
|
||||
inline const void* test_output_impl(const char* v) { return v; }
|
||||
inline const void* test_output_impl(const unsigned char* v) { return v; }
|
||||
inline const void* test_output_impl(const signed char* v) { return v; }
|
||||
inline const void* test_output_impl(char* v) { return v; }
|
||||
inline const void* test_output_impl(unsigned char* v) { return v; }
|
||||
inline const void* test_output_impl(signed char* v) { return v; }
|
||||
inline const void* test_output_impl(std::nullptr_t) { return nullptr; }
|
||||
|
||||
// print chars as numeric
|
||||
inline int test_output_impl( signed char const& v ) { return v; }
|
||||
inline unsigned test_output_impl( unsigned char const& v ) { return v; }
|
||||
|
||||
// Whether wchar_t is signed is implementation-defined
|
||||
template<bool Signed> struct lwt_long_type {};
|
||||
template<> struct lwt_long_type<true> { typedef long type; };
|
||||
template<> struct lwt_long_type<false> { typedef unsigned long type; };
|
||||
inline lwt_long_type<
|
||||
(static_cast<wchar_t>(-1) < static_cast<wchar_t>(0))
|
||||
>::type test_output_impl( wchar_t const& v ) { return v; }
|
||||
|
||||
#if !defined( BOOST_NO_CXX11_CHAR16_T )
|
||||
inline unsigned long test_output_impl( char16_t const& v ) { return v; }
|
||||
#endif
|
||||
|
||||
#if !defined( BOOST_NO_CXX11_CHAR32_T )
|
||||
inline unsigned long test_output_impl( char32_t const& v ) { return v; }
|
||||
#endif
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable: 4996)
|
||||
#endif
|
||||
|
||||
inline std::string test_output_impl( char const& v )
|
||||
{
|
||||
if( std::isprint( static_cast<unsigned char>( v ) ) )
|
||||
{
|
||||
return std::string( 1, v );
|
||||
}
|
||||
else
|
||||
{
|
||||
char buffer[ 8 ];
|
||||
std::sprintf( buffer, "\\x%02X", static_cast<unsigned char>( v ) );
|
||||
|
||||
return buffer;
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
|
||||
#if defined(__clang__) && defined(__has_warning)
|
||||
# if __has_warning("-Wsign-compare")
|
||||
# pragma clang diagnostic pop
|
||||
# endif
|
||||
#elif defined(_MSC_VER)
|
||||
# pragma warning(pop)
|
||||
#elif defined(__GNUC__) && !(defined(__INTEL_COMPILER) || defined(__ICL) || defined(__ICC) || defined(__ECC)) && (__GNUC__ * 100 + __GNUC_MINOR__) >= 406
|
||||
# pragma GCC diagnostic pop
|
||||
#endif
|
||||
|
||||
bool
|
||||
test_impl(
|
||||
bool cond,
|
||||
char const* expr,
|
||||
char const* func,
|
||||
char const* file,
|
||||
int line);
|
||||
|
||||
void
|
||||
throw_failed_impl(
|
||||
const char* expr,
|
||||
char const* excep,
|
||||
char const* func,
|
||||
char const* file,
|
||||
int line);
|
||||
|
||||
void
|
||||
no_throw_failed_impl(
|
||||
const char* expr,
|
||||
char const* excep,
|
||||
char const* func,
|
||||
char const* file,
|
||||
int line);
|
||||
|
||||
void
|
||||
no_throw_failed_impl(
|
||||
const char* expr,
|
||||
char const* func,
|
||||
char const* file,
|
||||
int line);
|
||||
|
||||
// In the comparisons below, it is possible that
|
||||
// T and U are signed and unsigned integer types,
|
||||
// which generates warnings in some compilers.
|
||||
// A cleaner fix would require common_type trait
|
||||
// or some meta-programming, which would introduce
|
||||
// a dependency on Boost.TypeTraits. To avoid
|
||||
// the dependency we just disable the warnings.
|
||||
#if defined(__clang__) && defined(__has_warning)
|
||||
# if __has_warning("-Wsign-compare")
|
||||
# pragma clang diagnostic push
|
||||
# pragma clang diagnostic ignored "-Wsign-compare"
|
||||
# endif
|
||||
#elif defined(_MSC_VER)
|
||||
# pragma warning(push)
|
||||
# pragma warning(disable: 4389)
|
||||
#elif defined(__GNUC__) && !(defined(__INTEL_COMPILER) || defined(__ICL) || defined(__ICC) || defined(__ECC)) && (__GNUC__ * 100 + __GNUC_MINOR__) >= 406
|
||||
# pragma GCC diagnostic push
|
||||
# pragma GCC diagnostic ignored "-Wsign-compare"
|
||||
#endif
|
||||
|
||||
struct lw_test_eq
|
||||
{
|
||||
template <typename T, typename U>
|
||||
bool operator()(const T& t, const U& u) const { return t == u; }
|
||||
};
|
||||
|
||||
struct lw_test_ne
|
||||
{
|
||||
template <typename T, typename U>
|
||||
bool operator()(const T& t, const U& u) const { return t != u; }
|
||||
};
|
||||
|
||||
struct lw_test_lt
|
||||
{
|
||||
template <typename T, typename U>
|
||||
bool operator()(const T& t, const U& u) const { return t < u; }
|
||||
};
|
||||
|
||||
struct lw_test_le
|
||||
{
|
||||
template <typename T, typename U>
|
||||
bool operator()(const T& t, const U& u) const { return t <= u; }
|
||||
};
|
||||
|
||||
struct lw_test_gt
|
||||
{
|
||||
template <typename T, typename U>
|
||||
bool operator()(const T& t, const U& u) const { return t > u; }
|
||||
};
|
||||
|
||||
struct lw_test_ge
|
||||
{
|
||||
template <typename T, typename U>
|
||||
bool operator()(const T& t, const U& u) const { return t >= u; }
|
||||
};
|
||||
|
||||
// lwt_predicate_name
|
||||
|
||||
template<class T> char const * lwt_predicate_name( T const& )
|
||||
{
|
||||
return "~=";
|
||||
}
|
||||
|
||||
inline char const * lwt_predicate_name( lw_test_eq const& )
|
||||
{
|
||||
return "==";
|
||||
}
|
||||
|
||||
inline char const * lwt_predicate_name( lw_test_ne const& )
|
||||
{
|
||||
return "!=";
|
||||
}
|
||||
|
||||
inline char const * lwt_predicate_name( lw_test_lt const& )
|
||||
{
|
||||
return "<";
|
||||
}
|
||||
|
||||
inline char const * lwt_predicate_name( lw_test_le const& )
|
||||
{
|
||||
return "<=";
|
||||
}
|
||||
|
||||
inline char const * lwt_predicate_name( lw_test_gt const& )
|
||||
{
|
||||
return ">";
|
||||
}
|
||||
|
||||
inline char const * lwt_predicate_name( lw_test_ge const& )
|
||||
{
|
||||
return ">=";
|
||||
}
|
||||
|
||||
//------------------------------------------------
|
||||
|
||||
template<class Pred, class T, class U>
|
||||
bool
|
||||
test_with_impl(
|
||||
Pred pred,
|
||||
char const* expr1,
|
||||
char const* expr2,
|
||||
char const* func,
|
||||
char const* file,
|
||||
int line,
|
||||
T const& t, U const& u)
|
||||
{
|
||||
if(pred(t, u))
|
||||
{
|
||||
any_runner::instance().test(true, "", func, file, line);
|
||||
return true;
|
||||
}
|
||||
std::stringstream ss;
|
||||
ss <<
|
||||
"'" << test_output_impl(t) << "' " <<
|
||||
lwt_predicate_name(pred) <<
|
||||
" '" << test_output_impl(u) << "' (" <<
|
||||
expr1 << "' " <<
|
||||
lwt_predicate_name(pred) <<
|
||||
" '" << expr2 << "')";
|
||||
any_runner::instance().test(false, ss.str().c_str(), func, file, line);
|
||||
return false;
|
||||
}
|
||||
|
||||
#if defined(__clang__) && defined(__has_warning)
|
||||
# if __has_warning("-Wsign-compare")
|
||||
# pragma clang diagnostic pop
|
||||
# endif
|
||||
#elif defined(_MSC_VER)
|
||||
# pragma warning(pop)
|
||||
#elif defined(__GNUC__) && !(defined(__INTEL_COMPILER) || defined(__ICL) || defined(__ICC) || defined(__ECC)) && (__GNUC__ * 100 + __GNUC_MINOR__) >= 406
|
||||
# pragma GCC diagnostic pop
|
||||
#endif
|
||||
|
||||
//----------------------------------------------------------
|
||||
|
||||
struct log_type
|
||||
{
|
||||
template<class T>
|
||||
friend
|
||||
std::ostream&
|
||||
operator<<(
|
||||
log_type const&, T&& t)
|
||||
{
|
||||
return stream() << t;
|
||||
}
|
||||
|
||||
private:
|
||||
static std::ostream& stream() noexcept;
|
||||
};
|
||||
|
||||
//----------------------------------------------------------
|
||||
|
||||
} // detail
|
||||
|
||||
/** Log output to the current suite
|
||||
*/
|
||||
constexpr detail::log_type log{};
|
||||
|
||||
#define BOOST_TEST(expr) ( \
|
||||
::test_suite::detail::test_impl( \
|
||||
(expr) ? true : false, #expr, \
|
||||
BOOST_CURRENT_FUNCTION, __FILE__, __LINE__ ) )
|
||||
|
||||
#define BOOST_ERROR(msg) \
|
||||
::test_suite::detail::test_impl( \
|
||||
false, msg, BOOST_CURRENT_FUNCTION, __FILE__, __LINE__ )
|
||||
|
||||
#define BOOST_TEST_WITH(expr1,expr2,predicate) ( \
|
||||
::test_suite::detail::test_with_impl( \
|
||||
predicate, #expr1, #expr2, BOOST_CURRENT_FUNCTION, \
|
||||
__FILE__, __LINE__, expr1, expr2) )
|
||||
|
||||
#define BOOST_TEST_EQ(expr1,expr2) \
|
||||
BOOST_TEST_WITH( expr1, expr2, \
|
||||
::test_suite::detail::lw_test_eq() )
|
||||
|
||||
#define BOOST_TEST_NE(expr1,expr2) \
|
||||
BOOST_TEST_WITH( expr1, expr2, \
|
||||
::test_suite::detail::lw_test_ne() )
|
||||
|
||||
#define BOOST_TEST_LT(expr1,expr2) \
|
||||
BOOST_TEST_WITH( expr1, expr2, \
|
||||
::test_suite::detail::lw_test_lt() )
|
||||
|
||||
#define BOOST_TEST_LE(expr1,expr2) \
|
||||
BOOST_TEST_WITH( expr1, expr2, \
|
||||
::test_suite::detail::lw_test_le() )
|
||||
|
||||
#define BOOST_TEST_GT(expr1,expr2) \
|
||||
BOOST_TEST_WITH( expr1, expr2, \
|
||||
::test_suite::detail::lw_test_gt() )
|
||||
|
||||
#define BOOST_TEST_GE(expr1,expr2) \
|
||||
BOOST_TEST_WITH( expr1, expr2, \
|
||||
::test_suite::detail::lw_test_ge() )
|
||||
|
||||
#define BOOST_TEST_PASS() BOOST_TEST(true)
|
||||
|
||||
#define BOOST_TEST_FAIL() BOOST_TEST(false)
|
||||
|
||||
#define BOOST_TEST_NOT(expr) BOOST_TEST(!(expr))
|
||||
|
||||
#ifndef BOOST_NO_EXCEPTIONS
|
||||
# define BOOST_TEST_THROWS( expr, ex ) \
|
||||
try { \
|
||||
(void)(expr); \
|
||||
::test_suite::detail::throw_failed_impl( \
|
||||
#expr, #ex, BOOST_CURRENT_FUNCTION, \
|
||||
__FILE__, __LINE__); \
|
||||
} \
|
||||
catch(ex const&) { \
|
||||
BOOST_TEST_PASS(); \
|
||||
} \
|
||||
catch(...) { \
|
||||
::test_suite::detail::throw_failed_impl( \
|
||||
#expr, #ex, BOOST_CURRENT_FUNCTION, \
|
||||
__FILE__, __LINE__); \
|
||||
}
|
||||
//
|
||||
#else
|
||||
#define BOOST_TEST_THROWS( expr, ex )
|
||||
#endif
|
||||
|
||||
#ifndef BOOST_NO_EXCEPTIONS
|
||||
# define BOOST_TEST_NO_THROW( expr ) \
|
||||
try { \
|
||||
(void)(expr); \
|
||||
BOOST_TEST_PASS(); \
|
||||
} catch (const std::exception& e) { \
|
||||
::test_suite::detail::no_throw_failed_impl( \
|
||||
#expr, e.what(), BOOST_CURRENT_FUNCTION, \
|
||||
__FILE__, __LINE__); \
|
||||
} catch (...) { \
|
||||
::test_suite::detail::no_throw_failed_impl( \
|
||||
#expr, BOOST_CURRENT_FUNCTION, \
|
||||
__FILE__, __LINE__); \
|
||||
}
|
||||
//
|
||||
#else
|
||||
# define BOOST_TEST_NO_THROW( expr ) ( [&]{ expr; return true; }() )
|
||||
#endif
|
||||
|
||||
#define TEST_SUITE(type, name) \
|
||||
static ::test_suite::suite<type> type##_(name)
|
||||
|
||||
} // test_suite
|
||||
|
||||
#endif
|
@ -13,6 +13,7 @@ if(NOT TARGET boost_url_all_tests)
|
||||
set_property(TARGET boost_url_all_tests PROPERTY FOLDER Dependencies)
|
||||
endif()
|
||||
|
||||
add_subdirectory(extra)
|
||||
add_subdirectory(limits)
|
||||
add_subdirectory(unit)
|
||||
#add_subdirectory(wpt)
|
||||
|
@ -7,5 +7,6 @@
|
||||
# Official repository: https://github.com/vinniefalco/url
|
||||
#
|
||||
|
||||
build-project extra ;
|
||||
build-project limits ;
|
||||
build-project unit ;
|
||||
|
41
test/extra/CMakeLists.txt
Normal file
41
test/extra/CMakeLists.txt
Normal file
@ -0,0 +1,41 @@
|
||||
#
|
||||
# Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com)
|
||||
# Copyright (c) 2021 DMitry Arkhipov (grisumbras@gmail.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/CPPAlliance/url
|
||||
#
|
||||
|
||||
set(TEST_FILES
|
||||
Jamfile
|
||||
test_suite.cpp
|
||||
)
|
||||
|
||||
file(GLOB_RECURSE SUITE_FILES CONFIGURE_DEPENDS
|
||||
../../extra/*.cpp
|
||||
../../extra/*.hpp
|
||||
../../extra/*.ipp
|
||||
)
|
||||
|
||||
#set(SUITE_FILES ../../extra/test_main.cpp ../../extra/test_suite.hpp)
|
||||
|
||||
source_group(TREE ${CMAKE_CURRENT_SOURCE_DIR} FILES ${TEST_FILES})
|
||||
source_group(TREE ${CMAKE_CURRENT_SOURCE_DIR}/../../extra PREFIX "_extra" FILES ${SUITE_FILES})
|
||||
add_executable(boost_url_extra ${TEST_FILES} ${SUITE_FILES})
|
||||
target_include_directories(boost_url_extra PRIVATE . ../../extra)
|
||||
if (BOOST_URL_FIND_PACKAGE_BOOST)
|
||||
target_link_libraries(boost_url_extra PRIVATE Boost::headers)
|
||||
else()
|
||||
target_link_libraries(boost_url_extra PRIVATE
|
||||
Boost::align
|
||||
Boost::config
|
||||
Boost::core
|
||||
Boost::optional
|
||||
Boost::type_traits
|
||||
Boost::system
|
||||
Boost::variant2)
|
||||
endif()
|
||||
add_test(NAME boost_url_extra COMMAND boost_url_extra)
|
||||
add_dependencies(boost_url_all_tests boost_url_extra)
|
28
test/extra/Jamfile
Normal file
28
test/extra/Jamfile
Normal file
@ -0,0 +1,28 @@
|
||||
#
|
||||
# Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.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/CPPAlliance/url
|
||||
#
|
||||
|
||||
import testing ;
|
||||
|
||||
project
|
||||
: requirements
|
||||
$(c11-requires)
|
||||
<source>../../extra/test_main.cpp
|
||||
<include>.
|
||||
<include>../../extra
|
||||
;
|
||||
|
||||
|
||||
local SOURCES =
|
||||
test_suite.cpp
|
||||
;
|
||||
|
||||
for local f in $(SOURCES)
|
||||
{
|
||||
run $(f) ../../extra/test_main.cpp ;
|
||||
}
|
12
test/extra/test_suite.cpp
Normal file
12
test/extra/test_suite.cpp
Normal file
@ -0,0 +1,12 @@
|
||||
//
|
||||
// Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.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/CPPAlliance/url
|
||||
//
|
||||
|
||||
// Test that header file is self-contained.
|
||||
#include "test_suite.hpp"
|
||||
|
@ -7,13 +7,13 @@
|
||||
# Official repository: https://github.com/CPPAlliance/url
|
||||
#
|
||||
|
||||
set(TEST_MAIN ../../extra/test_main.cpp)
|
||||
set(SUITE_FILES ../../extra/test_main.cpp ../../extra/test_suite.hpp)
|
||||
|
||||
source_group(TREE ${CMAKE_CURRENT_SOURCE_DIR} FILES limits.cpp Jamfile)
|
||||
source_group(TREE ${CMAKE_CURRENT_SOURCE_DIR}/../../extra PREFIX "_extra" FILES ${TEST_MAIN})
|
||||
source_group(TREE ${CMAKE_CURRENT_SOURCE_DIR}/../../extra PREFIX "_extra" FILES ${SUITE_FILES})
|
||||
source_group(TREE ${CMAKE_CURRENT_SOURCE_DIR}/../../src PREFIX "_extra" FILES ../../src/src.cpp)
|
||||
add_executable(boost_url_limits limits.cpp Jamfile ${TEST_MAIN} ../../src/src.cpp)
|
||||
target_include_directories(boost_url_limits PRIVATE ../../include ../../extra/include ../../..)
|
||||
add_executable(boost_url_limits limits.cpp Jamfile ${SUITE_FILES} ../../src/src.cpp)
|
||||
target_include_directories(boost_url_limits PRIVATE ../../include ../../extra ../../..)
|
||||
target_compile_definitions(boost_url_limits PRIVATE
|
||||
BOOST_URL_MAX_SIZE=16
|
||||
BOOST_URL_NO_LIB=1
|
||||
|
@ -14,7 +14,7 @@ project
|
||||
$(c11-requires)
|
||||
<source>../../extra/test_main.cpp
|
||||
<include>.
|
||||
<include>../../extra/include
|
||||
<include>../../extra
|
||||
;
|
||||
|
||||
run limits.cpp ../../extra/test_main.cpp /boost/url//url_sources
|
||||
|
@ -88,12 +88,12 @@ set(BOOST_URL_TESTS_FILES
|
||||
rfc/uri_reference_rule.cpp
|
||||
)
|
||||
|
||||
set(TEST_MAIN ../../extra/test_main.cpp)
|
||||
set(SUITE_FILES ../../extra/test_main.cpp ../../extra/test_suite.hpp)
|
||||
|
||||
source_group(TREE ${CMAKE_CURRENT_SOURCE_DIR} FILES ${BOOST_URL_TESTS_FILES})
|
||||
source_group(TREE ${CMAKE_CURRENT_SOURCE_DIR}/../../extra PREFIX "_extra" FILES ${TEST_MAIN})
|
||||
add_executable(boost_url_tests ${BOOST_URL_TESTS_FILES} ${TEST_MAIN})
|
||||
target_include_directories(boost_url_tests PRIVATE . ../../extra/include)
|
||||
source_group(TREE ${CMAKE_CURRENT_SOURCE_DIR}/../../extra PREFIX "_extra" FILES ${SUITE_FILES})
|
||||
add_executable(boost_url_tests ${BOOST_URL_TESTS_FILES} ${SUITE_FILES})
|
||||
target_include_directories(boost_url_tests PRIVATE . ../../extra)
|
||||
# The include dependencies are found in the CMakeLists.txt
|
||||
# of the root project directory.
|
||||
# See: BOOST_URL_UNIT_TEST_LIBRARIES
|
||||
|
@ -16,7 +16,7 @@ project
|
||||
<library>/boost/filesystem//boost_filesystem/<warnings>off
|
||||
<source>../../extra/test_main.cpp
|
||||
<include>.
|
||||
<include>../../extra/include
|
||||
<include>../../extra
|
||||
;
|
||||
|
||||
|
||||
|
@ -11,6 +11,7 @@
|
||||
#include <boost/url/grammar/type_traits.hpp>
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "test_suite.hpp"
|
||||
|
||||
|
@ -196,66 +196,21 @@ public:
|
||||
opt.non_normal_is_error = false;
|
||||
opt.plus_to_space = false;
|
||||
|
||||
{
|
||||
BOOST_TEST_CHECKPOINT();
|
||||
good("", "");
|
||||
}
|
||||
{
|
||||
BOOST_TEST_CHECKPOINT();
|
||||
good("%20", " ");
|
||||
}
|
||||
{
|
||||
BOOST_TEST_CHECKPOINT();
|
||||
good("A", "A");
|
||||
}
|
||||
{
|
||||
BOOST_TEST_CHECKPOINT();
|
||||
good("%41", "A");
|
||||
}
|
||||
{
|
||||
BOOST_TEST_CHECKPOINT();
|
||||
good("%42", "B");
|
||||
}
|
||||
{
|
||||
BOOST_TEST_CHECKPOINT();
|
||||
good("A%42", "AB");
|
||||
}
|
||||
{
|
||||
BOOST_TEST_CHECKPOINT();
|
||||
good("A%20%42", "A B");
|
||||
}
|
||||
{
|
||||
BOOST_TEST_CHECKPOINT();
|
||||
good("%00", "\0");
|
||||
}
|
||||
{
|
||||
BOOST_TEST_CHECKPOINT();
|
||||
good("+", "+");
|
||||
}
|
||||
{
|
||||
BOOST_TEST_CHECKPOINT();
|
||||
good("A%00+", "A\0+");
|
||||
}
|
||||
{
|
||||
BOOST_TEST_CHECKPOINT();
|
||||
bad("B");
|
||||
}
|
||||
{
|
||||
BOOST_TEST_CHECKPOINT();
|
||||
bad("%");
|
||||
}
|
||||
{
|
||||
BOOST_TEST_CHECKPOINT();
|
||||
bad("%1");
|
||||
}
|
||||
{
|
||||
BOOST_TEST_CHECKPOINT();
|
||||
bad("%1x");
|
||||
}
|
||||
{
|
||||
BOOST_TEST_CHECKPOINT();
|
||||
bad("%%");
|
||||
}
|
||||
good("", "");
|
||||
good("%20", " ");
|
||||
good("A", "A");
|
||||
good("%41", "A");
|
||||
good("%42", "B");
|
||||
good("A%42", "AB");
|
||||
good("A%20%42", "A B");
|
||||
good("%00", "\0");
|
||||
good("+", "+");
|
||||
good("A%00+", "A\0+");
|
||||
bad("B");
|
||||
bad("%");
|
||||
bad("%1");
|
||||
bad("%1x");
|
||||
bad("%%");
|
||||
}
|
||||
|
||||
{
|
||||
@ -264,66 +219,21 @@ public:
|
||||
opt.non_normal_is_error = false;
|
||||
opt.plus_to_space = false;
|
||||
|
||||
{
|
||||
BOOST_TEST_CHECKPOINT();
|
||||
good("", "");
|
||||
}
|
||||
{
|
||||
BOOST_TEST_CHECKPOINT();
|
||||
good("%20", " ");
|
||||
}
|
||||
{
|
||||
BOOST_TEST_CHECKPOINT();
|
||||
good("A", "A");
|
||||
}
|
||||
{
|
||||
BOOST_TEST_CHECKPOINT();
|
||||
good("%41", "A");
|
||||
}
|
||||
{
|
||||
BOOST_TEST_CHECKPOINT();
|
||||
good("%42", "B");
|
||||
}
|
||||
{
|
||||
BOOST_TEST_CHECKPOINT();
|
||||
good("A%42", "AB");
|
||||
}
|
||||
{
|
||||
BOOST_TEST_CHECKPOINT();
|
||||
good("A%20%42", "A B");
|
||||
}
|
||||
{
|
||||
BOOST_TEST_CHECKPOINT();
|
||||
good("+", "+");
|
||||
}
|
||||
{
|
||||
BOOST_TEST_CHECKPOINT();
|
||||
bad("B");
|
||||
}
|
||||
{
|
||||
BOOST_TEST_CHECKPOINT();
|
||||
bad("%00");
|
||||
}
|
||||
{
|
||||
BOOST_TEST_CHECKPOINT();
|
||||
bad("%");
|
||||
}
|
||||
{
|
||||
BOOST_TEST_CHECKPOINT();
|
||||
bad("%1");
|
||||
}
|
||||
{
|
||||
BOOST_TEST_CHECKPOINT();
|
||||
bad("%1x");
|
||||
}
|
||||
{
|
||||
BOOST_TEST_CHECKPOINT();
|
||||
bad("%%");
|
||||
}
|
||||
{
|
||||
BOOST_TEST_CHECKPOINT();
|
||||
bad("A%00+");
|
||||
}
|
||||
good("", "");
|
||||
good("%20", " ");
|
||||
good("A", "A");
|
||||
good("%41", "A");
|
||||
good("%42", "B");
|
||||
good("A%42", "AB");
|
||||
good("A%20%42", "A B");
|
||||
good("+", "+");
|
||||
bad("B");
|
||||
bad("%00");
|
||||
bad("%");
|
||||
bad("%1");
|
||||
bad("%1x");
|
||||
bad("%%");
|
||||
bad("A%00+");
|
||||
}
|
||||
|
||||
{
|
||||
@ -332,66 +242,21 @@ public:
|
||||
opt.non_normal_is_error = true;
|
||||
opt.plus_to_space = false;
|
||||
|
||||
{
|
||||
BOOST_TEST_CHECKPOINT();
|
||||
good("", "");
|
||||
}
|
||||
{
|
||||
BOOST_TEST_CHECKPOINT();
|
||||
good("%20", " ");
|
||||
}
|
||||
{
|
||||
BOOST_TEST_CHECKPOINT();
|
||||
good("A", "A");
|
||||
}
|
||||
{
|
||||
BOOST_TEST_CHECKPOINT();
|
||||
bad("%41");
|
||||
}
|
||||
{
|
||||
BOOST_TEST_CHECKPOINT();
|
||||
good("%42", "B");
|
||||
}
|
||||
{
|
||||
BOOST_TEST_CHECKPOINT();
|
||||
good("A%42", "AB");
|
||||
}
|
||||
{
|
||||
BOOST_TEST_CHECKPOINT();
|
||||
good("A%20%42", "A B");
|
||||
}
|
||||
{
|
||||
BOOST_TEST_CHECKPOINT();
|
||||
good("%00", "\0");
|
||||
}
|
||||
{
|
||||
BOOST_TEST_CHECKPOINT();
|
||||
good("+", "+");
|
||||
}
|
||||
{
|
||||
BOOST_TEST_CHECKPOINT();
|
||||
good("A%00+", "A\0+");
|
||||
}
|
||||
{
|
||||
BOOST_TEST_CHECKPOINT();
|
||||
bad("B");
|
||||
}
|
||||
{
|
||||
BOOST_TEST_CHECKPOINT();
|
||||
bad("%");
|
||||
}
|
||||
{
|
||||
BOOST_TEST_CHECKPOINT();
|
||||
bad("%1");
|
||||
}
|
||||
{
|
||||
BOOST_TEST_CHECKPOINT();
|
||||
bad("%1x");
|
||||
}
|
||||
{
|
||||
BOOST_TEST_CHECKPOINT();
|
||||
bad("%%");
|
||||
}
|
||||
good("", "");
|
||||
good("%20", " ");
|
||||
good("A", "A");
|
||||
bad("%41");
|
||||
good("%42", "B");
|
||||
good("A%42", "AB");
|
||||
good("A%20%42", "A B");
|
||||
good("%00", "\0");
|
||||
good("+", "+");
|
||||
good("A%00+", "A\0+");
|
||||
bad("B");
|
||||
bad("%");
|
||||
bad("%1");
|
||||
bad("%1x");
|
||||
bad("%%");
|
||||
}
|
||||
|
||||
{
|
||||
@ -400,66 +265,21 @@ public:
|
||||
opt.non_normal_is_error = false;
|
||||
opt.plus_to_space = false;
|
||||
|
||||
{
|
||||
BOOST_TEST_CHECKPOINT();
|
||||
good("", "");
|
||||
}
|
||||
{
|
||||
BOOST_TEST_CHECKPOINT();
|
||||
good("%20", " ");
|
||||
}
|
||||
{
|
||||
BOOST_TEST_CHECKPOINT();
|
||||
good("A", "A");
|
||||
}
|
||||
{
|
||||
BOOST_TEST_CHECKPOINT();
|
||||
good("%41", "A");
|
||||
}
|
||||
{
|
||||
BOOST_TEST_CHECKPOINT();
|
||||
good("%42", "B");
|
||||
}
|
||||
{
|
||||
BOOST_TEST_CHECKPOINT();
|
||||
good("A%42", "AB");
|
||||
}
|
||||
{
|
||||
BOOST_TEST_CHECKPOINT();
|
||||
good("A%20%42", "A B");
|
||||
}
|
||||
{
|
||||
BOOST_TEST_CHECKPOINT();
|
||||
good("%00", "\0");
|
||||
}
|
||||
{
|
||||
BOOST_TEST_CHECKPOINT();
|
||||
good("+", "+");
|
||||
}
|
||||
{
|
||||
BOOST_TEST_CHECKPOINT();
|
||||
good("A%00+", "A\0+");
|
||||
}
|
||||
{
|
||||
BOOST_TEST_CHECKPOINT();
|
||||
bad("B");
|
||||
}
|
||||
{
|
||||
BOOST_TEST_CHECKPOINT();
|
||||
bad("%");
|
||||
}
|
||||
{
|
||||
BOOST_TEST_CHECKPOINT();
|
||||
bad("%1");
|
||||
}
|
||||
{
|
||||
BOOST_TEST_CHECKPOINT();
|
||||
bad("%1x");
|
||||
}
|
||||
{
|
||||
BOOST_TEST_CHECKPOINT();
|
||||
bad("%%");
|
||||
}
|
||||
good("", "");
|
||||
good("%20", " ");
|
||||
good("A", "A");
|
||||
good("%41", "A");
|
||||
good("%42", "B");
|
||||
good("A%42", "AB");
|
||||
good("A%20%42", "A B");
|
||||
good("%00", "\0");
|
||||
good("+", "+");
|
||||
good("A%00+", "A\0+");
|
||||
bad("B");
|
||||
bad("%");
|
||||
bad("%1");
|
||||
bad("%1x");
|
||||
bad("%%");
|
||||
}
|
||||
|
||||
{
|
||||
@ -468,66 +288,21 @@ public:
|
||||
opt.non_normal_is_error = false;
|
||||
opt.plus_to_space = true;
|
||||
|
||||
{
|
||||
BOOST_TEST_CHECKPOINT();
|
||||
good("", "");
|
||||
}
|
||||
{
|
||||
BOOST_TEST_CHECKPOINT();
|
||||
good("%20", " ");
|
||||
}
|
||||
{
|
||||
BOOST_TEST_CHECKPOINT();
|
||||
good("A", "A");
|
||||
}
|
||||
{
|
||||
BOOST_TEST_CHECKPOINT();
|
||||
good("%41", "A");
|
||||
}
|
||||
{
|
||||
BOOST_TEST_CHECKPOINT();
|
||||
good("%42", "B");
|
||||
}
|
||||
{
|
||||
BOOST_TEST_CHECKPOINT();
|
||||
good("A%42", "AB");
|
||||
}
|
||||
{
|
||||
BOOST_TEST_CHECKPOINT();
|
||||
good("A%20%42", "A B");
|
||||
}
|
||||
{
|
||||
BOOST_TEST_CHECKPOINT();
|
||||
good("%00", "\0");
|
||||
}
|
||||
{
|
||||
BOOST_TEST_CHECKPOINT();
|
||||
good("+", " ");
|
||||
}
|
||||
{
|
||||
BOOST_TEST_CHECKPOINT();
|
||||
bad("B");
|
||||
}
|
||||
{
|
||||
BOOST_TEST_CHECKPOINT();
|
||||
bad("%");
|
||||
}
|
||||
{
|
||||
BOOST_TEST_CHECKPOINT();
|
||||
bad("%1");
|
||||
}
|
||||
{
|
||||
BOOST_TEST_CHECKPOINT();
|
||||
bad("%1x");
|
||||
}
|
||||
{
|
||||
BOOST_TEST_CHECKPOINT();
|
||||
bad("%%");
|
||||
}
|
||||
{
|
||||
BOOST_TEST_CHECKPOINT();
|
||||
good("A%00+", "A\0 ");
|
||||
}
|
||||
good("", "");
|
||||
good("%20", " ");
|
||||
good("A", "A");
|
||||
good("%41", "A");
|
||||
good("%42", "B");
|
||||
good("A%42", "AB");
|
||||
good("A%20%42", "A B");
|
||||
good("%00", "\0");
|
||||
good("+", " ");
|
||||
bad("B");
|
||||
bad("%");
|
||||
bad("%1");
|
||||
bad("%1x");
|
||||
bad("%%");
|
||||
good("A%00+", "A\0 ");
|
||||
}
|
||||
|
||||
{
|
||||
@ -536,22 +311,10 @@ public:
|
||||
opt.non_normal_is_error = false;
|
||||
opt.plus_to_space = true;
|
||||
|
||||
{
|
||||
BOOST_TEST_CHECKPOINT();
|
||||
good("\0", "\0");
|
||||
}
|
||||
{
|
||||
BOOST_TEST_CHECKPOINT();
|
||||
good("A\0", "A\0");
|
||||
}
|
||||
{
|
||||
BOOST_TEST_CHECKPOINT();
|
||||
good("%41\0", "A\0");
|
||||
}
|
||||
{
|
||||
BOOST_TEST_CHECKPOINT();
|
||||
good("%41%00", "A\0");
|
||||
}
|
||||
good("\0", "\0");
|
||||
good("A\0", "A\0");
|
||||
good("%41\0", "A\0");
|
||||
good("%41%00", "A\0");
|
||||
}
|
||||
|
||||
{
|
||||
@ -560,22 +323,10 @@ public:
|
||||
opt.non_normal_is_error = false;
|
||||
opt.plus_to_space = true;
|
||||
|
||||
{
|
||||
BOOST_TEST_CHECKPOINT();
|
||||
bad("\0");
|
||||
}
|
||||
{
|
||||
BOOST_TEST_CHECKPOINT();
|
||||
bad("A\0");
|
||||
}
|
||||
{
|
||||
BOOST_TEST_CHECKPOINT();
|
||||
bad("%41\0");
|
||||
}
|
||||
{
|
||||
BOOST_TEST_CHECKPOINT();
|
||||
bad("%41%00");
|
||||
}
|
||||
bad("\0");
|
||||
bad("A\0");
|
||||
bad("%41\0");
|
||||
bad("%41%00");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
//
|
||||
//
|
||||
// Copyright (c) 2022 Alan Freitas (alandefreitas@gmail.com)
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
|
@ -13,8 +13,11 @@
|
||||
|
||||
#include <boost/url/url_view.hpp>
|
||||
#include <boost/url/rfc/detail/charsets.hpp>
|
||||
|
||||
#include "test_suite.hpp"
|
||||
|
||||
#include <algorithm>
|
||||
#include <iomanip>
|
||||
#include <sstream>
|
||||
|
||||
namespace boost {
|
||||
|
@ -20,7 +20,7 @@ set(F
|
||||
|
||||
source_group(TREE ${CMAKE_CURRENT_SOURCE_DIR} PREFIX "" FILES ${F})
|
||||
add_executable(boost_wpt_tests ${F})
|
||||
target_include_directories(boost_wpt_tests PRIVATE . ../../extra/include)
|
||||
target_include_directories(boost_wpt_tests PRIVATE . ../../extra)
|
||||
target_link_libraries(boost_wpt_tests PRIVATE Boost::url Boost::json)
|
||||
add_test(NAME boost_url_tests COMMAND boost_url_tests)
|
||||
add_dependencies(tests boost_url_tests)
|
||||
|
Loading…
x
Reference in New Issue
Block a user