• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
nameempty_testcase13 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 {
runtestrange21     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> {
runtestrange47     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;
errmsgerrmsg67     errmsg() : msg(new std::stringstream)
68     {}
69 
70     template <class T>
operator <<errmsg71     errmsg& operator<<(T value)
72     {
73         (*msg) << value;
74         return *this;
75     }
strerrmsg76     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