89 lines
2.4 KiB
C++
89 lines
2.4 KiB
C++
|
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
|
||
|
|
||
|
#pragma once
|
||
|
|
||
|
#include <iostream>
|
||
|
#include <iomanip>
|
||
|
#include <exception>
|
||
|
#include <sstream>
|
||
|
#include <utility>
|
||
|
#include <memory>
|
||
|
#include <cstddef>
|
||
|
|
||
|
struct empty_testcase{ void run(){} const char* name(){return 0;} };
|
||
|
|
||
|
template <std::size_t offset>
|
||
|
struct testcase : empty_testcase{};
|
||
|
|
||
|
|
||
|
template <std::size_t begin, std::size_t end>
|
||
|
struct testrange {
|
||
|
void run(std::size_t& pass, std::size_t& fail)
|
||
|
{
|
||
|
using namespace std;
|
||
|
{ testcase<begin> a_case;
|
||
|
if (a_case.name()) {
|
||
|
std::size_t p=0, f=0;
|
||
|
cout << "TEST: Running " << a_case.name() << endl;
|
||
|
try {
|
||
|
a_case.run();
|
||
|
++p;
|
||
|
} catch (logic_error& e) {
|
||
|
cerr << "ERRORS:" << endl;
|
||
|
cerr << " " << e.what() << endl;
|
||
|
++f;
|
||
|
}
|
||
|
pass += p; fail += f;
|
||
|
}
|
||
|
}
|
||
|
const std::size_t rem = (end-begin-1);
|
||
|
testrange<begin+1, begin+1+rem/2>().run(pass, fail);
|
||
|
testrange<begin+1+rem/2, end>().run(pass, fail);
|
||
|
}
|
||
|
};
|
||
|
|
||
|
template <std::size_t begin>
|
||
|
struct testrange<begin,begin> {
|
||
|
void run(std::size_t& pass, std::size_t& fail) {};
|
||
|
};
|
||
|
|
||
|
#define TEST(fun_name) \
|
||
|
void fun_name (); \
|
||
|
template <> \
|
||
|
struct testcase<__LINE__> { \
|
||
|
const char* name() { return(#fun_name); } \
|
||
|
void run() { fun_name(); } \
|
||
|
}; \
|
||
|
void fun_name()
|
||
|
|
||
|
#define Q_(e) #e
|
||
|
#define Q(e) Q_(e)
|
||
|
#define TASSERT(expr) \
|
||
|
{ auto e = (expr); if (!e) { throw std::logic_error(__FILE__ "(" Q(__LINE__) "): TASSERT("#expr")"); } }
|
||
|
|
||
|
struct errmsg
|
||
|
{
|
||
|
std::shared_ptr<std::stringstream> msg;
|
||
|
errmsg() : msg(new std::stringstream)
|
||
|
{}
|
||
|
|
||
|
template <class T>
|
||
|
errmsg& operator<<(T value)
|
||
|
{
|
||
|
(*msg) << value;
|
||
|
return *this;
|
||
|
}
|
||
|
std::string str() { return msg->str(); }
|
||
|
};
|
||
|
|
||
|
#define TEST_WHERE __FILE__ "(" Q(__LINE__) "): "
|
||
|
#define VERIFY(expr) \
|
||
|
{ auto e = (expr); if (!e) { throw std::logic_error(TEST_WHERE "VERIFY("#expr")"); } }
|
||
|
#define VERIFY_EQ(expected, actual) \
|
||
|
{ auto e = (expected); auto a = (actual); \
|
||
|
if (!(e == a)) { \
|
||
|
throw std::logic_error( \
|
||
|
(errmsg() << TEST_WHERE << "(" << e << ")!=(" << a << ") in VERIFY_EQ("#expected","#actual")").str() );}}
|
||
|
|
||
|
|