1 // Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. 2 3 #pragma once 4 5 #include <iostream> 6 #include <iomanip> 7 #include <exception> 8 #include <sstream> 9 #include <utility> 10 #include <memory> 11 #include <cstddef> 12 13 struct empty_testcase{ void run(){} const char* name(){return 0;} }; 14 15 template <std::size_t offset> 16 struct testcase : empty_testcase{}; 17 18 19 template <std::size_t begin, std::size_t end> 20 struct testrange { 21 void run(std::size_t& pass, std::size_t& fail) 22 { 23 using namespace std; 24 { testcase<begin> a_case; 25 if (a_case.name()) { 26 std::size_t p=0, f=0; 27 cout << "TEST: Running " << a_case.name() << endl; 28 try { 29 a_case.run(); 30 ++p; 31 } catch (logic_error& e) { 32 cerr << "ERRORS:" << endl; 33 cerr << " " << e.what() << endl; 34 ++f; 35 } 36 pass += p; fail += f; 37 } 38 } 39 const std::size_t rem = (end-begin-1); 40 testrange<begin+1, begin+1+rem/2>().run(pass, fail); 41 testrange<begin+1+rem/2, end>().run(pass, fail); 42 } 43 }; 44 45 template <std::size_t begin> 46 struct testrange<begin,begin> { 47 void run(std::size_t& pass, std::size_t& fail) {}; 48 }; 49 50 #define TEST(fun_name) \ 51 void fun_name (); \ 52 template <> \ 53 struct testcase<__LINE__> { \ 54 const char* name() { return(#fun_name); } \ 55 void run() { fun_name(); } \ 56 }; \ 57 void fun_name() 58 59 #define Q_(e) #e 60 #define Q(e) Q_(e) 61 #define TASSERT(expr) \ 62 { auto e = (expr); if (!e) { throw std::logic_error(__FILE__ "(" Q(__LINE__) "): TASSERT("#expr")"); } } 63 64 struct errmsg 65 { 66 std::shared_ptr<std::stringstream> msg; 67 errmsg() : msg(new std::stringstream) 68 {} 69 70 template <class T> 71 errmsg& operator<<(T value) 72 { 73 (*msg) << value; 74 return *this; 75 } 76 std::string str() { return msg->str(); } 77 }; 78 79 #define TEST_WHERE __FILE__ "(" Q(__LINE__) "): " 80 #define VERIFY(expr) \ 81 { auto e = (expr); if (!e) { throw std::logic_error(TEST_WHERE "VERIFY("#expr")"); } } 82 #define VERIFY_EQ(expected, actual) \ 83 { auto e = (expected); auto a = (actual); \ 84 if (!(e == a)) { \ 85 throw std::logic_error( \ 86 (errmsg() << TEST_WHERE << "(" << e << ")!=(" << a << ") in VERIFY_EQ("#expected","#actual")").str() );}} 87 88 89