1 /*
2  * Copyright (C) 2020 Linux Studio Plugins Project <https://lsp-plug.in/>
3  *           (C) 2020 Vladimir Sadovnikov <sadko4u@gmail.com>
4  *
5  * This file is part of lsp-plugins
6  * Created on: 19 авг. 2018 г.
7  *
8  * lsp-plugins is free software: you can redistribute it and/or modify
9  * it under the terms of the GNU Lesser General Public License as published by
10  * the Free Software Foundation, either version 3 of the License, or
11  * any later version.
12  *
13  * lsp-plugins is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU Lesser General Public License for more details.
17  *
18  * You should have received a copy of the GNU Lesser General Public License
19  * along with lsp-plugins. If not, see <https://www.gnu.org/licenses/>.
20  */
21 
22 #ifndef TEST_UTEST_H_
23 #define TEST_UTEST_H_
24 
25 #include <stdio.h>
26 #include <stddef.h>
27 #include <stdint.h>
28 #include <stdlib.h>
29 #include <time.h>
30 #include <test/test.h>
31 
32 #define UTEST_BEGIN(group, name) \
33         namespace utest { \
34         namespace { \
35             \
36             using namespace ::test; \
37             \
38             class utest_ ## name: public UnitTest { \
39                 public: \
40                     typedef utest_ ## name test_type_t;\
41                 \
42                 public: \
43                     \
44                     _Pragma("GCC diagnostic push") \
45                     _Pragma("GCC diagnostic ignored \"-Wuninitialized\"") \
46                     explicit utest_ ## name() : UnitTest(group, #name) {} \
47                     _Pragma("GCC diagnostic pop") \
48                     \
49                     virtual ~utest_ ## name() {}
50 
51 #define UTEST_TIMELIMIT(seconds) \
52         virtual double time_limit() const { return double(seconds); }
53 
54 #define UTEST_IGNORE \
55         virtual bool ignore() const { return true; }
56 
57 #define UTEST_MAIN \
58         virtual void execute(int argc, const char **argv)
59 
60 #define UTEST_INIT \
61         virtual void init()
62 
63 #define UTEST_DESTROY \
64         virtual void destroy()
65 
66 #define UTEST_SUPPORTED(ptr)        TEST_SUPPORTED(ptr)
67 
68 #define UTEST_FAIL_MSG(message, ...) {  \
69             ::fprintf(stderr, "Unit test '%s.%s' has failed at file %s, line %d with message: \n  " message  "\n", \
70                     __test_group, __test_name, __FILE__, __LINE__, ## __VA_ARGS__); \
71             ::exit(1); \
72         }
73 
74 #define UTEST_FAIL() {\
75             ::fprintf(stderr, "Unit test '%s.%s' has failed at file %s, line %d\n", \
76                     __test_group, __test_name, __FILE__, __LINE__); \
77             ::exit(1); \
78         }
79 
80 #define UTEST_ASSERT(code) \
81         if (!(code)) { \
82             ::fprintf(stderr, "Unit test '%s.%s' assertion has failed at file %s, line %d:\n  %s\n", \
83                     __test_group, __test_name, __FILE__, __LINE__, # code); \
84             ::exit(2); \
85         }
86 
87 #define UTEST_ASSERT_MSG(code, message, ...) \
88         if (!(code)) { \
89             ::fprintf(stderr, "Unit test '%s.%s' assertion has failed at file %s, line %d:\n  %s\n  " message "\n", \
90                     __test_group, __test_name, __FILE__, __LINE__, # code, ## __VA_ARGS__); \
91             ::exit(2); \
92         }
93 
94 #define UTEST_FOREACH(var, ...)    \
95         const size_t ___sizes[] = { __VA_ARGS__, 0 }; \
96         for (size_t ___i=0, var=___sizes[0]; ___i<(sizeof(___sizes)/sizeof(size_t) - 1); var=___sizes[++___i])
97 
98 #define UTEST_END \
99         } unit_test;  /* utest class */ \
100         } /* anonymous namespace */ \
101         } /* namespace utest */
102 
103 namespace test
104 {
105     class UnitTest: public Test
106     {
107         private:
108             friend UnitTest *utest_init();
109 
110         private:
111             static UnitTest        *__root;
112             UnitTest               *__next;
113 
114         public:
115             explicit UnitTest(const char *group, const char *name);
116             virtual ~UnitTest();
117 
118         public:
next()119             inline UnitTest *next()                 { return __next; }
120 
next_test()121             virtual Test *next_test() const         { return const_cast<UnitTest *>(__next); };
122 
123         public:
124             virtual double time_limit() const;
125     };
126 
127 
128     /**
129      * Initialize set of performance tests (validate duplicates, etc)
130      * @return valid set of performance tests
131      */
132     UnitTest *utest_init();
133 }
134 
135 #endif /* TEST_UTEST_H_ */
136