Tizen 2.0 Release
[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 #include <map>
36
37 namespace DPL
38 {
39 namespace Test
40 {
41 class TestRunner
42 {
43     typedef std::map<std::string, TestResultsCollectorBasePtr>
44             TestResultsCollectors;
45     TestResultsCollectors m_collectors;
46
47     std::string m_startTestId;
48     bool m_runIgnored;
49
50 public:
51     typedef void (*TestCase)();
52
53 private:
54     struct TestCaseStruct
55     {
56         std::string name;
57         TestCase proc;
58
59         bool operator <(const TestCaseStruct &other) const
60         {
61             return name < other.name;
62         }
63
64         bool operator ==(const TestCaseStruct &other) const
65         {
66             return name == other.name;
67         }
68
69         TestCaseStruct(const std::string &n, TestCase p)
70             : name(n),
71               proc(p)
72         {
73         }
74     };
75
76     typedef std::list<TestCaseStruct> TestCaseStructList;
77     typedef std::map<std::string, TestCaseStructList> TestCaseGroupMap;
78     TestCaseGroupMap m_testGroups;
79
80     typedef std::set<std::string> SelectedTestNameSet;
81     SelectedTestNameSet m_selectedTestNamesSet;
82     typedef std::set<std::string> SelectedTestGroupSet;
83     SelectedTestGroupSet m_selectedTestGroupSet;
84     std::string m_currentGroup;
85
86     DPL::Atomic m_totalAssertions;
87
88     void Banner();
89     void InvalidArgs(const std::string& message = "Invalid arguments!");
90     void Usage();
91
92     enum Status { FAILED, IGNORED, PASS };
93
94     Status RunTestCase(const TestCaseStruct& testCase);
95
96     void RunTests();
97
98     void CollectResult(const std::string& id,
99                        const std::string& description,
100                        const TestResultsCollectorBase::FailStatus::Type status
101                            = TestResultsCollectorBase::FailStatus::NONE,
102                        const std::string& reason = std::string());
103
104 public:
105     class TestFailed
106     {
107     private:
108         std::string m_message;
109
110     public:
111         TestFailed()
112         {
113         }
114
115         //! \brief Failed test message creator
116         //!
117         //! \param[in] aTest string for tested expression
118         //! \param[in] aFile source file name
119         //! \param[in] aLine source file line
120         //! \param[in] aMessage error message
121         TestFailed(const char* aTest, const char* aFile, int aLine, const std::string &aMessage);
122
123         std::string GetMessage() const
124         {
125             return m_message;
126         }
127     };
128
129     class Ignored
130     {
131     private:
132         std::string m_message;
133
134     public:
135         Ignored()
136         {
137         }
138
139         Ignored(const std::string &message)
140             : m_message(message)
141         {
142         }
143
144         std::string GetMessage() const
145         {
146             return m_message;
147         }
148     };
149
150     void MarkAssertion();
151
152     void RegisterTest(const char *testName, TestCase proc);
153     void InitGroup(const char* name);
154
155     int ExecTestRunner(int argc, char *argv[]);
156     typedef std::vector<std::string> ArgsList;
157     int ExecTestRunner(const ArgsList& args);
158     bool getRunIgnored() const;
159 };
160
161 typedef DPL::Singleton<TestRunner> TestRunnerSingleton;
162
163 }
164 } // namespace DPL
165
166 #define RUNNER_TEST_GROUP_INIT(GroupName)                                \
167     static int Static##GroupName##Init()                                 \
168     {                                                                    \
169         DPL::Test::TestRunnerSingleton::Instance().InitGroup(#GroupName);\
170         return 0;                                                        \
171     }                                                                    \
172     const int DPL_UNUSED  Static##GroupName##InitVar =                   \
173         Static##GroupName##Init();
174
175 #define RUNNER_TEST(Proc)                                                \
176     void Proc();                                                         \
177     static int Static##Proc##Init()                                      \
178     {                                                                    \
179         DPL::Test::TestRunnerSingleton::Instance().RegisterTest(#Proc, &Proc); \
180         return 0;                                                        \
181     }                                                                    \
182     const int DPL_UNUSED  Static##Proc##InitVar = Static##Proc##Init();  \
183     void Proc()
184
185 //! \brief Returns base name for path
186
187 #define RUNNER_ASSERT_MSG(test, message)                                               \
188 do                                                                                     \
189 {                                                                                      \
190     DPL::Test::TestRunnerSingleton::Instance().MarkAssertion();                        \
191                                                                                        \
192     if (!(test))                                                                       \
193     {                                                                                  \
194         std::ostringstream assertMsg;                                                  \
195         assertMsg << message;                                                          \
196         throw DPL::Test::TestRunner::TestFailed(#test, __FILE__, __LINE__, assertMsg.str()); \
197     }                                                                                  \
198 } while (0)
199
200 #define RUNNER_ASSERT(test) RUNNER_ASSERT_MSG(test, "")
201
202 #define RUNNER_FAIL RUNNER_ASSERT(false)
203
204 #define RUNNER_IGNORED_MSG(message) do { std::ostringstream assertMsg; assertMsg << message; throw DPL::Test::TestRunner::Ignored(assertMsg.str()); } while (0)
205
206 #endif // DPL_TEST_RUNNER_H