mirror of
https://github.com/boostorg/url.git
synced 2025-05-11 05:33:57 +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 "test_suite.hpp"
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
|
#include <atomic>
|
||||||
|
#include <chrono>
|
||||||
|
#include <cstring>
|
||||||
|
#include <iomanip>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
#include <ostream>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
#ifdef _MSC_VER
|
||||||
|
#define WIN32_LEAN_AND_MEAN
|
||||||
|
#include <windows.h>
|
||||||
|
#include <debugapi.h>
|
||||||
#include <crtdbg.h>
|
#include <crtdbg.h>
|
||||||
|
#include <sstream>
|
||||||
#endif
|
#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
|
// Simple main used to produce stand
|
||||||
// alone executables that run unit tests.
|
// alone executables that run unit tests.
|
||||||
int main(int argc, char const* const* argv)
|
int main(int argc, char const* const* argv)
|
||||||
{
|
{
|
||||||
#ifdef _MSC_VER
|
#ifdef _MSC_VER
|
||||||
{
|
int flags = _CrtSetDbgFlag(
|
||||||
int flags = _CrtSetDbgFlag(_CRTDBG_REPORT_FLAG);
|
_CRTDBG_REPORT_FLAG);
|
||||||
flags |= _CRTDBG_LEAK_CHECK_DF;
|
flags |= _CRTDBG_LEAK_CHECK_DF;
|
||||||
_CrtSetDbgFlag(flags);
|
_CrtSetDbgFlag(flags);
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
::test_suite::debug_stream log(std::cerr);
|
::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)
|
set_property(TARGET boost_url_all_tests PROPERTY FOLDER Dependencies)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
add_subdirectory(extra)
|
||||||
add_subdirectory(limits)
|
add_subdirectory(limits)
|
||||||
add_subdirectory(unit)
|
add_subdirectory(unit)
|
||||||
#add_subdirectory(wpt)
|
#add_subdirectory(wpt)
|
||||||
|
@ -7,5 +7,6 @@
|
|||||||
# Official repository: https://github.com/vinniefalco/url
|
# Official repository: https://github.com/vinniefalco/url
|
||||||
#
|
#
|
||||||
|
|
||||||
|
build-project extra ;
|
||||||
build-project limits ;
|
build-project limits ;
|
||||||
build-project unit ;
|
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
|
# 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} 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)
|
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)
|
add_executable(boost_url_limits limits.cpp Jamfile ${SUITE_FILES} ../../src/src.cpp)
|
||||||
target_include_directories(boost_url_limits PRIVATE ../../include ../../extra/include ../../..)
|
target_include_directories(boost_url_limits PRIVATE ../../include ../../extra ../../..)
|
||||||
target_compile_definitions(boost_url_limits PRIVATE
|
target_compile_definitions(boost_url_limits PRIVATE
|
||||||
BOOST_URL_MAX_SIZE=16
|
BOOST_URL_MAX_SIZE=16
|
||||||
BOOST_URL_NO_LIB=1
|
BOOST_URL_NO_LIB=1
|
||||||
|
@ -14,7 +14,7 @@ project
|
|||||||
$(c11-requires)
|
$(c11-requires)
|
||||||
<source>../../extra/test_main.cpp
|
<source>../../extra/test_main.cpp
|
||||||
<include>.
|
<include>.
|
||||||
<include>../../extra/include
|
<include>../../extra
|
||||||
;
|
;
|
||||||
|
|
||||||
run limits.cpp ../../extra/test_main.cpp /boost/url//url_sources
|
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
|
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} FILES ${BOOST_URL_TESTS_FILES})
|
||||||
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})
|
||||||
add_executable(boost_url_tests ${BOOST_URL_TESTS_FILES} ${TEST_MAIN})
|
add_executable(boost_url_tests ${BOOST_URL_TESTS_FILES} ${SUITE_FILES})
|
||||||
target_include_directories(boost_url_tests PRIVATE . ../../extra/include)
|
target_include_directories(boost_url_tests PRIVATE . ../../extra)
|
||||||
# The include dependencies are found in the CMakeLists.txt
|
# The include dependencies are found in the CMakeLists.txt
|
||||||
# of the root project directory.
|
# of the root project directory.
|
||||||
# See: BOOST_URL_UNIT_TEST_LIBRARIES
|
# See: BOOST_URL_UNIT_TEST_LIBRARIES
|
||||||
|
@ -16,7 +16,7 @@ project
|
|||||||
<library>/boost/filesystem//boost_filesystem/<warnings>off
|
<library>/boost/filesystem//boost_filesystem/<warnings>off
|
||||||
<source>../../extra/test_main.cpp
|
<source>../../extra/test_main.cpp
|
||||||
<include>.
|
<include>.
|
||||||
<include>../../extra/include
|
<include>../../extra
|
||||||
;
|
;
|
||||||
|
|
||||||
|
|
||||||
|
@ -11,6 +11,7 @@
|
|||||||
#include <boost/url/grammar/type_traits.hpp>
|
#include <boost/url/grammar/type_traits.hpp>
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
#include "test_suite.hpp"
|
#include "test_suite.hpp"
|
||||||
|
|
||||||
|
@ -196,66 +196,21 @@ public:
|
|||||||
opt.non_normal_is_error = false;
|
opt.non_normal_is_error = false;
|
||||||
opt.plus_to_space = false;
|
opt.plus_to_space = false;
|
||||||
|
|
||||||
{
|
good("", "");
|
||||||
BOOST_TEST_CHECKPOINT();
|
good("%20", " ");
|
||||||
good("", "");
|
good("A", "A");
|
||||||
}
|
good("%41", "A");
|
||||||
{
|
good("%42", "B");
|
||||||
BOOST_TEST_CHECKPOINT();
|
good("A%42", "AB");
|
||||||
good("%20", " ");
|
good("A%20%42", "A B");
|
||||||
}
|
good("%00", "\0");
|
||||||
{
|
good("+", "+");
|
||||||
BOOST_TEST_CHECKPOINT();
|
good("A%00+", "A\0+");
|
||||||
good("A", "A");
|
bad("B");
|
||||||
}
|
bad("%");
|
||||||
{
|
bad("%1");
|
||||||
BOOST_TEST_CHECKPOINT();
|
bad("%1x");
|
||||||
good("%41", "A");
|
bad("%%");
|
||||||
}
|
|
||||||
{
|
|
||||||
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("%%");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
@ -264,66 +219,21 @@ public:
|
|||||||
opt.non_normal_is_error = false;
|
opt.non_normal_is_error = false;
|
||||||
opt.plus_to_space = false;
|
opt.plus_to_space = false;
|
||||||
|
|
||||||
{
|
good("", "");
|
||||||
BOOST_TEST_CHECKPOINT();
|
good("%20", " ");
|
||||||
good("", "");
|
good("A", "A");
|
||||||
}
|
good("%41", "A");
|
||||||
{
|
good("%42", "B");
|
||||||
BOOST_TEST_CHECKPOINT();
|
good("A%42", "AB");
|
||||||
good("%20", " ");
|
good("A%20%42", "A B");
|
||||||
}
|
good("+", "+");
|
||||||
{
|
bad("B");
|
||||||
BOOST_TEST_CHECKPOINT();
|
bad("%00");
|
||||||
good("A", "A");
|
bad("%");
|
||||||
}
|
bad("%1");
|
||||||
{
|
bad("%1x");
|
||||||
BOOST_TEST_CHECKPOINT();
|
bad("%%");
|
||||||
good("%41", "A");
|
bad("A%00+");
|
||||||
}
|
|
||||||
{
|
|
||||||
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+");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
@ -332,66 +242,21 @@ public:
|
|||||||
opt.non_normal_is_error = true;
|
opt.non_normal_is_error = true;
|
||||||
opt.plus_to_space = false;
|
opt.plus_to_space = false;
|
||||||
|
|
||||||
{
|
good("", "");
|
||||||
BOOST_TEST_CHECKPOINT();
|
good("%20", " ");
|
||||||
good("", "");
|
good("A", "A");
|
||||||
}
|
bad("%41");
|
||||||
{
|
good("%42", "B");
|
||||||
BOOST_TEST_CHECKPOINT();
|
good("A%42", "AB");
|
||||||
good("%20", " ");
|
good("A%20%42", "A B");
|
||||||
}
|
good("%00", "\0");
|
||||||
{
|
good("+", "+");
|
||||||
BOOST_TEST_CHECKPOINT();
|
good("A%00+", "A\0+");
|
||||||
good("A", "A");
|
bad("B");
|
||||||
}
|
bad("%");
|
||||||
{
|
bad("%1");
|
||||||
BOOST_TEST_CHECKPOINT();
|
bad("%1x");
|
||||||
bad("%41");
|
bad("%%");
|
||||||
}
|
|
||||||
{
|
|
||||||
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("%%");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
@ -400,66 +265,21 @@ public:
|
|||||||
opt.non_normal_is_error = false;
|
opt.non_normal_is_error = false;
|
||||||
opt.plus_to_space = false;
|
opt.plus_to_space = false;
|
||||||
|
|
||||||
{
|
good("", "");
|
||||||
BOOST_TEST_CHECKPOINT();
|
good("%20", " ");
|
||||||
good("", "");
|
good("A", "A");
|
||||||
}
|
good("%41", "A");
|
||||||
{
|
good("%42", "B");
|
||||||
BOOST_TEST_CHECKPOINT();
|
good("A%42", "AB");
|
||||||
good("%20", " ");
|
good("A%20%42", "A B");
|
||||||
}
|
good("%00", "\0");
|
||||||
{
|
good("+", "+");
|
||||||
BOOST_TEST_CHECKPOINT();
|
good("A%00+", "A\0+");
|
||||||
good("A", "A");
|
bad("B");
|
||||||
}
|
bad("%");
|
||||||
{
|
bad("%1");
|
||||||
BOOST_TEST_CHECKPOINT();
|
bad("%1x");
|
||||||
good("%41", "A");
|
bad("%%");
|
||||||
}
|
|
||||||
{
|
|
||||||
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("%%");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
@ -468,66 +288,21 @@ public:
|
|||||||
opt.non_normal_is_error = false;
|
opt.non_normal_is_error = false;
|
||||||
opt.plus_to_space = true;
|
opt.plus_to_space = true;
|
||||||
|
|
||||||
{
|
good("", "");
|
||||||
BOOST_TEST_CHECKPOINT();
|
good("%20", " ");
|
||||||
good("", "");
|
good("A", "A");
|
||||||
}
|
good("%41", "A");
|
||||||
{
|
good("%42", "B");
|
||||||
BOOST_TEST_CHECKPOINT();
|
good("A%42", "AB");
|
||||||
good("%20", " ");
|
good("A%20%42", "A B");
|
||||||
}
|
good("%00", "\0");
|
||||||
{
|
good("+", " ");
|
||||||
BOOST_TEST_CHECKPOINT();
|
bad("B");
|
||||||
good("A", "A");
|
bad("%");
|
||||||
}
|
bad("%1");
|
||||||
{
|
bad("%1x");
|
||||||
BOOST_TEST_CHECKPOINT();
|
bad("%%");
|
||||||
good("%41", "A");
|
good("A%00+", "A\0 ");
|
||||||
}
|
|
||||||
{
|
|
||||||
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 ");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
@ -536,22 +311,10 @@ public:
|
|||||||
opt.non_normal_is_error = false;
|
opt.non_normal_is_error = false;
|
||||||
opt.plus_to_space = true;
|
opt.plus_to_space = true;
|
||||||
|
|
||||||
{
|
good("\0", "\0");
|
||||||
BOOST_TEST_CHECKPOINT();
|
good("A\0", "A\0");
|
||||||
good("\0", "\0");
|
good("%41\0", "A\0");
|
||||||
}
|
good("%41%00", "A\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");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
@ -560,22 +323,10 @@ public:
|
|||||||
opt.non_normal_is_error = false;
|
opt.non_normal_is_error = false;
|
||||||
opt.plus_to_space = true;
|
opt.plus_to_space = true;
|
||||||
|
|
||||||
{
|
bad("\0");
|
||||||
BOOST_TEST_CHECKPOINT();
|
bad("A\0");
|
||||||
bad("\0");
|
bad("%41\0");
|
||||||
}
|
bad("%41%00");
|
||||||
{
|
|
||||||
BOOST_TEST_CHECKPOINT();
|
|
||||||
bad("A\0");
|
|
||||||
}
|
|
||||||
{
|
|
||||||
BOOST_TEST_CHECKPOINT();
|
|
||||||
bad("%41\0");
|
|
||||||
}
|
|
||||||
{
|
|
||||||
BOOST_TEST_CHECKPOINT();
|
|
||||||
bad("%41%00");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
//
|
//
|
||||||
// Copyright (c) 2022 Alan Freitas (alandefreitas@gmail.com)
|
// Copyright (c) 2022 Alan Freitas (alandefreitas@gmail.com)
|
||||||
//
|
//
|
||||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||||
|
@ -13,8 +13,11 @@
|
|||||||
|
|
||||||
#include <boost/url/url_view.hpp>
|
#include <boost/url/url_view.hpp>
|
||||||
#include <boost/url/rfc/detail/charsets.hpp>
|
#include <boost/url/rfc/detail/charsets.hpp>
|
||||||
|
|
||||||
#include "test_suite.hpp"
|
#include "test_suite.hpp"
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
#include <iomanip>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
|
|
||||||
namespace boost {
|
namespace boost {
|
||||||
|
@ -20,7 +20,7 @@ set(F
|
|||||||
|
|
||||||
source_group(TREE ${CMAKE_CURRENT_SOURCE_DIR} PREFIX "" FILES ${F})
|
source_group(TREE ${CMAKE_CURRENT_SOURCE_DIR} PREFIX "" FILES ${F})
|
||||||
add_executable(boost_wpt_tests ${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)
|
target_link_libraries(boost_wpt_tests PRIVATE Boost::url Boost::json)
|
||||||
add_test(NAME boost_url_tests COMMAND boost_url_tests)
|
add_test(NAME boost_url_tests COMMAND boost_url_tests)
|
||||||
add_dependencies(tests boost_url_tests)
|
add_dependencies(tests boost_url_tests)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user