// 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() );}}