]> git.lizzy.rs Git - dragonfireclient.git/blob - src/unittest/test.h
test_map_settings_manager: Fix Wunused-result warning
[dragonfireclient.git] / src / unittest / test.h
1 /*
2 Minetest
3 Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@gmail.com>
4
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU Lesser General Public License as published by
7 the Free Software Foundation; either version 2.1 of the License, or
8 (at your option) any later version.
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 GNU Lesser General Public License for more details.
14
15 You should have received a copy of the GNU Lesser General Public License along
16 with this program; if not, write to the Free Software Foundation, Inc.,
17 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18 */
19
20 #ifndef TEST_HEADER
21 #define TEST_HEADER
22
23 #include <exception>
24 #include <vector>
25
26 #include "irrlichttypes_extrabloated.h"
27 #include "porting.h"
28 #include "filesys.h"
29 #include "mapnode.h"
30
31 class TestFailedException : public std::exception {
32 };
33
34 // Runs a unit test and reports results
35 #define TEST(fxn, ...) do {                                                   \
36         u32 t1 = porting::getTime(PRECISION_MILLI);                               \
37         try {                                                                     \
38                 fxn(__VA_ARGS__);                                                     \
39                 rawstream << "[PASS] ";                                               \
40         } catch (TestFailedException &e) {                                        \
41                 rawstream << "[FAIL] ";                                               \
42                 num_tests_failed++;                                                   \
43         } catch (std::exception &e) {                                             \
44                 rawstream << "Caught unhandled exception: " << e.what() << std::endl; \
45                 rawstream << "[FAIL] ";                                               \
46                 num_tests_failed++;                                                   \
47         }                                                                         \
48         num_tests_run++;                                                          \
49         u32 tdiff = porting::getTime(PRECISION_MILLI) - t1;                       \
50         rawstream << #fxn << " - " << tdiff << "ms" << std::endl;                 \
51 } while (0)
52
53 // Asserts the specified condition is true, or fails the current unit test
54 #define UASSERT(x) do {                                         \
55         if (!(x)) {                                                 \
56                 rawstream << "Test assertion failed: " #x << std::endl  \
57                         << "    at " << fs::GetFilenameFromPath(__FILE__)   \
58                         << ":" << __LINE__ << std::endl;                    \
59                 throw TestFailedException();                            \
60         }                                                           \
61 } while (0)
62
63 // Asserts the specified condition is true, or fails the current unit test
64 // and prints the format specifier fmt
65 #define UTEST(x, fmt, ...) do {                                          \
66         if (!(x)) {                                                          \
67                 char utest_buf[1024];                                            \
68                 snprintf(utest_buf, sizeof(utest_buf), fmt, __VA_ARGS__);        \
69                 rawstream << "Test assertion failed: " << utest_buf << std::endl \
70                         << "    at " << fs::GetFilenameFromPath(__FILE__)            \
71                         << ":" << __LINE__ << std::endl;                             \
72                 throw TestFailedException();                                     \
73         }                                                                    \
74 } while (0)
75
76 // Asserts the comparison specified by CMP is true, or fails the current unit test
77 #define UASSERTCMP(T, CMP, actual, expected) do {                         \
78         T a = (actual);                                                       \
79         T e = (expected);                                                     \
80         if (!(a CMP e)) {                                                     \
81                 rawstream                                                         \
82                         << "Test assertion failed: " << #actual << " " << #CMP << " " \
83                         << #expected << std::endl                                     \
84                         << "    at " << fs::GetFilenameFromPath(__FILE__) << ":"      \
85                         << __LINE__ << std::endl                                      \
86                         << "    actual:   " << a << std::endl << "    expected: "     \
87                         << e << std::endl;                                            \
88                 throw TestFailedException();                                      \
89         }                                                                     \
90 } while (0)
91
92 #define UASSERTEQ(T, actual, expected) UASSERTCMP(T, ==, actual, expected)
93
94 // UASSERTs that the specified exception occurs
95 #define EXCEPTION_CHECK(EType, code) do { \
96         bool exception_thrown = false;        \
97         try {                                 \
98                 code;                             \
99         } catch (EType &e) {                  \
100                 exception_thrown = true;          \
101         }                                     \
102         UASSERT(exception_thrown);            \
103 } while (0)
104
105 class IGameDef;
106
107 class TestBase {
108 public:
109         bool testModule(IGameDef *gamedef);
110         std::string getTestTempDirectory();
111         std::string getTestTempFile();
112
113         virtual void runTests(IGameDef *gamedef) = 0;
114         virtual const char *getName() = 0;
115
116         u32 num_tests_failed;
117         u32 num_tests_run;
118
119 private:
120         std::string m_test_dir;
121 };
122
123 class TestManager {
124 public:
125         static std::vector<TestBase *> &getTestModules()
126         {
127                 static std::vector<TestBase *> m_modules_to_test;
128                 return m_modules_to_test;
129         }
130
131         static void registerTestModule(TestBase *module)
132         {
133                 getTestModules().push_back(module);
134         }
135 };
136
137 // A few item and node definitions for those tests that need them
138 extern content_t t_CONTENT_STONE;
139 extern content_t t_CONTENT_GRASS;
140 extern content_t t_CONTENT_TORCH;
141 extern content_t t_CONTENT_WATER;
142 extern content_t t_CONTENT_LAVA;
143 extern content_t t_CONTENT_BRICK;
144
145 bool run_tests();
146
147 #endif