Jon Test
C++ Unit Test Tool. Not for production -- sample code only
Loading...
Searching...
No Matches
TestRunner.cpp
Go to the documentation of this file.
2
3#include "JonTest/Logger.h"
4#include "JonTest/TestSuite.h"
5
6#include <algorithm>
7#include <map>
8#include <utility>
9
10namespace
11{
24 typedef std::pair<std::string, std::string> TestName;
25
32 const std::string& test
33 )
34 {
35 const size_t separatorAt = test.find(":");
36 if(std::string::npos == separatorAt)
37 {
38 return std::make_pair(test, std::string());
39 }
40 else if((0 == separatorAt) || (test.length() -1 == separatorAt))
41 {
42 return std::make_pair(std::string(), std::string());
43 }
44 else
45 {
46 return std::make_pair(test.substr(0, separatorAt), test.substr(separatorAt + 1));
47 }
48 }
49}
50
51namespace JonTest
52{
53
55{
56 static TestRunner instance;
57 return instance;
58}
59
61 const char* const name,
63)
64{
65 // TODO: Error check this isn't overriding an existing test
66 suites[name] = suite;
67}
68
70 const std::string& test
71) const
72{
73 const TestName testName = parseTestName(test);
74
75 if(testName.first.empty())
76 {
77 return false;
78 }
79
80 // Check Suite
81 const auto suiteIter = suites.find(testName.first);
82 if(suites.end() == suiteIter)
83 {
84 return false;
85 }
86 if(testName.second.empty())
87 {
88 return true;
89 }
90
91 // Check case
92 return suiteIter->second->isValid(testName.second);
93}
94
96 std::ostream& out
97) const
98{
99 std::vector<std::string> names;
100 for(const auto& nameSuite : suites)
101 {
102 names.push_back(nameSuite.first);
103 }
104 std::sort(names.begin(), names.end());
105
106 out << "Available Test Suites:\n";
107 for(const auto& name : names)
108 {
109 out << "\t" << name << "\n";
110 }
111 out << suites.size() << " Test Suites\n";
112}
113
115 std::ostream& out
116) const
117{
118 std::vector<std::string> names;
119 for(const auto& nameSuite : suites)
120 {
121 names.push_back(nameSuite.first);
122 }
123 std::sort(names.begin(), names.end());
124
125 out << "Available Test Cases:\n";
126 int count = 0;
127 for(const auto& name : names)
128 {
129 const auto suite = suites.find(name);
130 if(suites.end() == suite)
131 {
132 out << "INTERNAL ERROR: Failed to find Test Suite " << name << "\n";
133 }
134 else
135 {
136 count += suite->second->listTestCases(out);
137 }
138 }
139 out << count << " Test Cases\n";
140}
141
144) const
145{
146 logger.start();
147
149 for(const auto& nameSuite : suites)
150 {
151 counts += nameSuite.second->run(logger);
152 }
153
154 logger.end(counts);
155 return counts;
156}
157
159 Logger& logger,
160 const TestNames& tests
161) const
162{
163 if(tests.empty())
164 {
165 return run(logger);
166 }
167
168 logger.start();
169
171 for(const auto& test : tests)
172 {
173 // Convenience check the argument and get the iterator. Makes logic cleaner.
174 const TestName testName = parseTestName(test);
175 const auto& nameSuite = suites.find(testName.first);
176 if(!isValid(test) || (suites.end() == nameSuite))
177 {
178 logger.errorCase(testName.first, testName.second, "not found", std::string("Test not found: \"") + test + "\"");
179 logger.endCase(testName.first, "(suite)", false);
180 }
181 else if(testName.second.empty())
182 {
183 counts += nameSuite->second->run(logger);
184 }
185 else
186 {
187 counts += nameSuite->second->run(logger, testName.second);
188 }
189 }
190
191 logger.end(counts);
192 return counts;
193}
194
195}
Count of tests run, and fails.
Definition Count.h:10
Interface for logging events while running tests.
Definition Logger.h:18
Defines and runs a single Test Case within a Test Suite.
Definition TestCase.h:18
bool run(TestSuite &suite, Logger &logger) const
Run this Test Case as part of suite, logging events to logger.
Definition TestCase.h:74
Singleton that collects all TEST_SUITE()s, to run on demand.
Definition TestRunner.h:20
bool isValid(const std::string &test) const
Determine if test can be run as one of: a valid Test Suite, or Test Suite:Test Case.
std::vector< std::string > TestNames
List of Test Names as: "<suite>" or "<suite>:<case>".
Definition TestRunner.h:30
Count run(Logger &logger) const
Run all tests that have been add()ed.
void listTestSuites(std::ostream &out) const
List available Test Suites to out.
void add(const char *const name, TestSuiteInterface *const suite)
Add the suite by name.
static TestRunner & get()
Get the singleton.
void listTestCases(std::ostream &out) const
List available Test Cases to out.
std::map< std::string, TestSuiteInterface * > suites
Mapping of test suite name to test suite.
Definition TestRunner.h:23
Interface for Test Suites.
Definition Count.h:5
std::pair< std::string, std::string > TestName
A parsed Test name as a Test Suite name (.first), and a Test Case name (.second).
TestName parseTestName(const std::string &test)
Parse test into a Test Suite Name and a Test Case name, which would be separated by a ":".