ab1a626a82357f0b0cdf9a0ac60a62664bd8ca82
[framework/web/wrt-commons.git] / modules / test / include / dpl / test / test_runner.h
1 /*
2  * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
3  *
4  *    Licensed under the Apache License, Version 2.0 (the "License");
5  *    you may not use this file except in compliance with the License.
6  *    You may obtain a copy of the License at
7  *
8  *        http://www.apache.org/licenses/LICENSE-2.0
9  *
10  *    Unless required by applicable law or agreed to in writing, software
11  *    distributed under the License is distributed on an "AS IS" BASIS,
12  *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  *    See the License for the specific language governing permissions and
14  *    limitations under the License.
15  */
16 /*
17  * @file        test_runner.h
18  * @author      Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com)
19  * @author      Lukasz Wrzosek (l.wrzosek@samsung.com)
20  * @version     1.0
21  * @brief       This file is the header file of test runner
22  */
23 #ifndef DPL_TEST_RUNNER_H
24 #define DPL_TEST_RUNNER_H
25
26 #include <dpl/singleton.h>
27 #include <dpl/unused.h>
28 #include <dpl/atomic.h>
29 #include <dpl/test/test_results_collector.h>
30 #include <sstream>
31 #include <string>
32 #include <vector>
33 #include <list>
34 #include <set>
35
36 namespace DPL
37 {
38 namespace Test
39 {
40 class TestRunner
41 {
42     TestResultsCollectorBasePtr m_collector;
43     std::string m_collectorName;
44     std::string m_startTestId;
45
46 public:
47     typedef void (*TestCase)();
48
49 private:
50     struct TestCaseStruct
51     {
52         std::string name;
53         TestCase proc;
54
55         bool operator <(const TestCaseStruct &other) const
56         {
57             return name < other.name;
58         }
59
60         bool operator ==(const TestCaseStruct &other) const
61         {
62             return name == other.name;
63         }
64
65         TestCaseStruct(const std::string &n, TestCase p)
66             : name(n),
67               proc(p)
68         {
69         }
70     };
71
72     typedef std::list<TestCaseStruct> TestCaseStructList;
73     typedef std::map<std::string, TestCaseStructList> TestCaseGroupMap;
74     TestCaseGroupMap m_testGroups;
75
76     typedef std::set<std::string> SelectedTestNameSet;
77     SelectedTestNameSet m_selectedTestNamesSet;
78     typedef std::set<std::string> SelectedTestGroupSet;
79     SelectedTestGroupSet m_selectedTestGroupSet;
80     std::string m_currentGroup;
81
82     DPL::Atomic m_totalAssertions;
83
84     void Banner();
85     void InvalidArgs();
86     void Usage();
87
88     enum Status { FAILED, TODO, IGNORED, PASS };
89
90     Status RunTestCase(const TestCaseStruct& testCase);
91
92     void RunTests();
93
94 public:
95     class TestFailed
96     {
97     private:
98         std::string m_message;
99
100     public:
101         TestFailed()
102         {
103         }
104
105         //! \brief Failed test message creator
106         //!
107         //! \param[in] aTest string for tested expression
108         //! \param[in] aFile source file name
109         //! \param[in] aLine source file line
110         //! \param[in] aMessage error message
111         TestFailed(const char* aTest, const char* aFile, int aLine, const std::string &aMessage);
112
113         std::string GetMessage() const
114         {
115             return m_message;
116         }
117     };
118
119     class ToDo
120     {
121     private:
122         std::string m_message;
123
124     public:
125         ToDo()
126         {
127         }
128
129         ToDo(const std::string &message)
130             : m_message(message)
131         {
132         }
133
134         std::string GetMessage() const
135         {
136             return m_message;
137         }
138     };
139
140     class Ignored
141     {
142     private:
143         std::string m_message;
144
145     public:
146         Ignored()
147         {
148         }
149
150         Ignored(const std::string &message)
151             : m_message(message)
152         {
153         }
154
155         std::string GetMessage() const
156         {
157             return m_message;
158         }
159     };
160
161     void MarkAssertion();
162
163     void RegisterTest(const char *testName, TestCase proc);
164     void InitGroup(const char* name);
165
166     int ExecTestRunner(int argc, char *argv[]);
167     typedef std::vector<std::string> ArgsList;
168     int ExecTestRunner(const ArgsList& args);
169 };
170
171 typedef DPL::Singleton<TestRunner> TestRunnerSingleton;
172
173 }
174 } // namespace DPL
175
176 #define RUNNER_TEST_GROUP_INIT(GroupName)                                \
177     static int Static##GroupName##Init()                                 \
178     {                                                                    \
179         DPL::Test::TestRunnerSingleton::Instance().InitGroup(#GroupName);\
180         return 0;                                                        \
181     }                                                                    \
182     const int DPL_UNUSED  Static##GroupName##InitVar =                   \
183         Static##GroupName##Init();
184
185 #define RUNNER_TEST(Proc)                                                \
186     void Proc();                                                         \
187     static int Static##Proc##Init()                                      \
188     {                                                                    \
189         DPL::Test::TestRunnerSingleton::Instance().RegisterTest(#Proc, &Proc); \
190         return 0;                                                        \
191     }                                                                    \
192     const int DPL_UNUSED  Static##Proc##InitVar = Static##Proc##Init();  \
193     void Proc()
194
195 //! \brief Returns base name for path
196
197 #define RUNNER_ASSERT_MSG(test, message)                                               \
198 do                                                                                     \
199 {                                                                                      \
200     DPL::Test::TestRunnerSingleton::Instance().MarkAssertion();                        \
201                                                                                        \
202     if (!(test))                                                                       \
203     {                                                                                  \
204         std::ostringstream assertMsg;                                                  \
205         assertMsg << message;                                                          \
206         throw DPL::Test::TestRunner::TestFailed(#test, __FILE__, __LINE__, assertMsg.str()); \
207     }                                                                                  \
208 } while (0)
209
210 #define RUNNER_ASSERT(test) RUNNER_ASSERT_MSG(test, "")
211
212 #define RUNNER_FAIL RUNNER_ASSERT(false)
213
214 #define RUNNER_TODO_MSG(message) do { std::ostringstream assertMsg; assertMsg << message; throw DPL::Test::TestRunner::ToDo(assertMsg.str()); } while (0)
215
216 #define RUNNER_IGNORED_MSG(message) do { std::ostringstream assertMsg; assertMsg << message; throw DPL::Test::TestRunner::Ignored(assertMsg.str()); } while (0)
217
218 #endif // DPL_TEST_RUNNER_H