1 | // |
2 | // TestRunner.cpp |
3 | // |
4 | |
5 | |
6 | #include "Poco/CppUnit/TestRunner.h" |
7 | #include "Poco/CppUnit/Test.h" |
8 | #include "Poco/CppUnit/TestSuite.h" |
9 | #include "Poco/CppUnit/TextTestResult.h" |
10 | #include <iostream> |
11 | |
12 | |
13 | namespace CppUnit { |
14 | |
15 | |
16 | TestRunner::TestRunner(): |
17 | _ostr(std::cout) |
18 | { |
19 | } |
20 | |
21 | |
22 | TestRunner::TestRunner(std::ostream& ostr): |
23 | _ostr(ostr) |
24 | { |
25 | } |
26 | |
27 | |
28 | TestRunner::~TestRunner() |
29 | { |
30 | for (Mappings::iterator it = _mappings.begin(); it != _mappings.end(); ++it) |
31 | delete it->second; |
32 | } |
33 | |
34 | |
35 | void TestRunner::printBanner() |
36 | { |
37 | _ostr |
38 | << "Usage: driver [-all] [-print] [-wait] [-setup <string>] [name] ..." << std::endl |
39 | << " where name is the name of a test case class" << std::endl; |
40 | } |
41 | |
42 | |
43 | bool TestRunner::run(const std::vector<std::string>& args) |
44 | { |
45 | std::string testCase; |
46 | int numberOfTests = 0; |
47 | bool success = true; |
48 | bool all = false; |
49 | bool wait = false; |
50 | bool printed = false; |
51 | std::vector<std::string> setup; |
52 | |
53 | for (int i = 1; i < args.size(); i++) |
54 | { |
55 | const std::string& arg = args[i]; |
56 | if (arg == "-wait" ) |
57 | { |
58 | wait = true; |
59 | continue; |
60 | } |
61 | else if (arg == "-all" ) |
62 | { |
63 | all = true; |
64 | continue; |
65 | } |
66 | else if (arg == "-print" ) |
67 | { |
68 | for (Mappings::iterator it = _mappings.begin(); it != _mappings.end(); ++it) |
69 | { |
70 | print(it->first, it->second, 0); |
71 | } |
72 | printed = true; |
73 | continue; |
74 | } |
75 | else if (arg == "-setup" ) |
76 | { |
77 | if (i + 1 < args.size()) |
78 | setup.push_back(args[++i]); |
79 | |
80 | continue; |
81 | } |
82 | |
83 | if (!all) |
84 | { |
85 | testCase = arg; |
86 | |
87 | if (testCase == "" ) |
88 | { |
89 | printBanner(); |
90 | return false; |
91 | } |
92 | |
93 | Test* testToRun = 0; |
94 | for (Mappings::iterator it = _mappings.begin(); !testToRun && it != _mappings.end(); ++it) |
95 | { |
96 | testToRun = find(testCase, it->second, it->first); |
97 | } |
98 | if (testToRun) |
99 | { |
100 | if (setup.size() > 0) |
101 | testToRun->addSetup(setup); |
102 | if (!run(testToRun)) success = false; |
103 | } |
104 | numberOfTests++; |
105 | |
106 | if (!testToRun) |
107 | { |
108 | _ostr << "Test " << testCase << " not found." << std::endl; |
109 | return false; |
110 | } |
111 | } |
112 | } |
113 | |
114 | if (all) |
115 | { |
116 | for (Mappings::iterator it = _mappings.begin(); it != _mappings.end(); ++it) |
117 | { |
118 | if (setup.size() > 0) |
119 | it->second->addSetup(setup); |
120 | if (!run(it->second)) success = false; |
121 | numberOfTests++; |
122 | } |
123 | } |
124 | |
125 | if (numberOfTests == 0 && !printed) |
126 | { |
127 | printBanner(); |
128 | return false; |
129 | } |
130 | |
131 | if (wait) |
132 | { |
133 | _ostr << "<RETURN> to continue" << std::endl; |
134 | std::cin.get(); |
135 | } |
136 | |
137 | return success; |
138 | } |
139 | |
140 | |
141 | bool TestRunner::run(Test* test) |
142 | { |
143 | TextTestResult result(_ostr); |
144 | |
145 | test->run(&result); |
146 | _ostr << result << std::endl; |
147 | |
148 | return result.wasSuccessful(); |
149 | } |
150 | |
151 | |
152 | void TestRunner::addTest(const std::string& name, Test* test) |
153 | { |
154 | _mappings.push_back(Mapping(name, test)); |
155 | } |
156 | |
157 | |
158 | void TestRunner::print(const std::string& name, Test* pTest, int indent) |
159 | { |
160 | for (int i = 0; i < indent; ++i) |
161 | _ostr << " " ; |
162 | _ostr << name << std::endl; |
163 | TestSuite* pSuite = dynamic_cast<TestSuite*>(pTest); |
164 | if (pSuite) |
165 | { |
166 | const std::vector<Test*>& tests = pSuite->tests(); |
167 | for (std::vector<Test*>::const_iterator it = tests.begin(); it != tests.end(); ++it) |
168 | { |
169 | print((*it)->toString(), *it, indent + 1); |
170 | } |
171 | } |
172 | } |
173 | |
174 | |
175 | Test* TestRunner::find(const std::string& name, Test* pTest, const std::string& testName) |
176 | { |
177 | if (testName.find(name) != std::string::npos) |
178 | { |
179 | return pTest; |
180 | } |
181 | else |
182 | { |
183 | TestSuite* pSuite = dynamic_cast<TestSuite*>(pTest); |
184 | if (pSuite) |
185 | { |
186 | const std::vector<Test*>& tests = pSuite->tests(); |
187 | for (std::vector<Test*>::const_iterator it = tests.begin(); it != tests.end(); ++it) |
188 | { |
189 | Test* result = find(name, *it, (*it)->toString()); |
190 | if (result) return result; |
191 | } |
192 | } |
193 | return 0; |
194 | } |
195 | } |
196 | |
197 | |
198 | } // namespace CppUnit |
199 | |