]> git.tdb.fi Git - libs/test.git/blob - source/test.h
Initial commit
[libs/test.git] / source / test.h
1 #ifndef MSP_TEST_TEST_H_
2 #define MSP_TEST_TEST_H_
3
4 #include <list>
5 #include <string>
6 #include <msp/strings/format.h>
7 #include "function.h"
8
9 namespace Msp {
10 namespace Test {
11
12 #define EXPECT(c) expect(c, #c)
13 #define EXPECT_EQUAL(a, b) expect_equal(a, a==b, #a " == " #b)
14
15 class test_failed: public std::exception
16 {
17 private:
18         std::string what_;
19
20 public:
21         test_failed(const std::string &w): what_(w) { }
22         virtual ~test_failed() throw() { }
23
24         const char *what() const throw() { return what_.c_str(); }
25 };
26
27
28 class Test
29 {
30 public:
31         class Factory
32         {
33         protected:
34                 Factory();
35
36         public:
37                 virtual const char *get_name() const = 0;
38                 virtual Test *create() const = 0;
39         };
40
41 private:
42         std::string name;
43         std::list<Function *> functions;
44         std::string detail_info;
45         std::string detail_debug;
46         bool passed;
47
48 protected:
49         Test(const std::string &);
50 public:
51         virtual ~Test();
52
53         static std::list<Factory *> &get_factories();
54
55 protected:
56         template<typename T>
57         Function &add(void (T::*f)(), const std::string &d)
58         {
59                 functions.push_back(new TypedFunction<T>(f, d));
60                 return *functions.back();
61         }
62
63 public:
64         static void run_single(const std::string &, bool);
65         static void run_all(bool);
66
67         void run(bool);
68 private:
69         void start_test(const std::string &);
70         void pass_test();
71         void fail_test(const std::string &);
72
73 protected:
74         void expect(bool, const std::string &);
75
76         template<typename T>
77         void expect_equal(const T &var, bool cond, const std::string &expr)
78         {
79                 if(!cond)
80                         throw test_failed(format("!(%s)\nActual: %s", expr, var));
81                 debug(expr);
82         }
83
84         void info(const std::string &);
85         void debug(const std::string &);
86 };
87
88 template<typename T>
89 class RegisteredTest: public Test
90 {
91 private:
92         class Factory: public Test::Factory
93         {
94         public:
95                 virtual const char *get_name() const { return T::get_name(); }
96                 virtual Test *create() const { return new T; }
97         };
98
99         static Factory factory;
100
101 protected:
102         RegisteredTest(): Test(T::get_name()) { (void)factory; }
103 };
104
105 template<typename T>
106 typename RegisteredTest<T>::Factory RegisteredTest<T>::factory;
107
108 } // namespace Test
109 } // namespace Msp
110
111 #endif