CPUnit 0.95 (beta)
The REAL C++ port of JUnit.
|
00001 /* 00002 Copyright (c) 2011 Daniel Bakkelund. 00003 All rights reserved. 00004 00005 Redistribution and use in source and binary forms, with or without 00006 modification, are permitted provided that the following conditions 00007 are met: 00008 1. Redistributions of source code must retain the above copyright 00009 notice, this list of conditions and the following disclaimer. 00010 2. Redistributions in binary form must reproduce the above copyright 00011 notice, this list of conditions and the following disclaimer in the 00012 documentation and/or other materials provided with the distribution. 00013 3. Neither the name of the copyright holders nor the names of its 00014 contributors may be used to endorse or promote products derived from 00015 this software without specific prior written permission. 00016 00017 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 00018 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 00019 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 00020 ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 00021 LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 00022 CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 00023 SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 00024 INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 00025 CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 00026 ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 00027 THE POSSIBILITY OF SUCH DAMAGE. 00028 */ 00029 00030 00031 00032 #include "cpunit_TestStore.hpp" 00033 #include "cpunit_TestTreeNode.hpp" 00034 #include "cpunit_TestUnit.hpp" 00035 #include "cpunit_GlobMatcher.hpp" 00036 #include "cpunit_trace.hpp" 00037 00038 cpunit::TestStore *cpunit::TestStore::INSTANCE(NULL); 00039 00043 cpunit::TestStore::TestStore() 00044 : root(new TestTreeNode("")) 00045 {} 00046 00052 cpunit::TestStore::~TestStore() 00053 {} 00054 00062 void 00063 cpunit::TestStore::dispose() { 00064 CPUNIT_DTRACE("TestStore::dispose()"); 00065 delete INSTANCE; 00066 INSTANCE = NULL; 00067 CPUNIT_DTRACE("TestStore - disposed."); 00068 } 00069 00074 cpunit::TestStore& cpunit::TestStore::get_instance() { 00075 if (INSTANCE == NULL) { 00076 INSTANCE = new TestStore; 00077 } 00078 return *INSTANCE; 00079 } 00080 00088 void 00089 cpunit::TestStore::insert_set_up(Callable *su) { 00090 CPUNIT_ITRACE("TestStore::insert_set_up for "<<su->get_reg_info().get_path()); 00091 TestTreeNode *n = find_node(su->get_reg_info().get_path(), true); 00092 n->register_set_up(su); 00093 } 00094 00102 void 00103 cpunit::TestStore::insert_tear_down(Callable *td) { 00104 CPUNIT_ITRACE("TestStore::insert_tear_down for "<<td->get_reg_info().get_path()); 00105 TestTreeNode *n = find_node(td->get_reg_info().get_path(), true); 00106 n->register_tear_down(td); 00107 } 00108 00115 void 00116 cpunit::TestStore::insert_test(Callable *test) { 00117 CPUNIT_ITRACE("TestStore::insert_test in "<<test->get_reg_info().get_path()<<": "<<test->get_reg_info().get_name()); 00118 TestTreeNode *n = find_node(test->get_reg_info().get_path(), true); 00119 n->add_test(test); 00120 } 00121 00128 std::vector<cpunit::TestUnit> 00129 cpunit::TestStore::get_test_units(const std::string &pattern) { 00130 std::vector<TestUnit> result; 00131 GlobMatcher m(pattern); 00132 root->extract_matches(result, m); 00133 return result; 00134 } 00135 00142 std::vector<cpunit::RegInfo> 00143 cpunit::TestStore::get_tests(const std::string &pattern) { 00144 std::vector<TestUnit> tus = get_test_units(pattern); 00145 std::vector<RegInfo> result(tus.size()); 00146 for (std::size_t i=0; i<tus.size(); i++) { 00147 result[i] = tus[i].get_test()->get_reg_info(); 00148 } 00149 return result; 00150 } 00151 00159 std::vector<std::string> 00160 cpunit::TestStore::decompose_path(const std::string& path) const { 00161 static const std::string sep("::"); 00162 00163 std::vector<std::string> result; 00164 00165 std::string str = path; 00166 if (str.find(sep) == 0) { 00167 str = str.substr(sep.length()); 00168 } 00169 00170 std::size_t index; 00171 while ((index = str.find(sep)) != std::string::npos) { 00172 result.push_back(str.substr(0, index)); 00173 str = str.substr(index + sep.length()); 00174 } 00175 if (str.length() > 0) { 00176 result.push_back(str); 00177 } 00178 return result; 00179 } 00180 00188 cpunit::TestTreeNode* 00189 cpunit::TestStore::find_node(const std::string& path, const bool createIfNonExisting) { 00190 CPUNIT_DTRACE("TestStore::find_node("<<path<<", "<<createIfNonExisting<<')'); 00191 std::vector<std::string> path_elts = decompose_path(path); 00192 TestTreeNode *current = root.get(); 00193 for (std::size_t i=0; i<path_elts.size(); i++) { 00194 CPUNIT_DTRACE("TestStore::find_node - i="<<i<<" path_elts["<<i<<"]='"<<path_elts[i]<<"' current='"<<current->get_path()<<'\''); 00195 std::map<std::string, TestTreeNode*> children = current->get_children(); 00196 std::map<std::string, TestTreeNode*>::iterator next = children.find(path_elts[i]); 00197 if (next != children.end()) { 00198 CPUNIT_DTRACE("TestStore::find_node - has next"); 00199 current = next->second; 00200 } else if (createIfNonExisting) { 00201 CPUNIT_DTRACE("TestStore::find_node - creating next: '"<<path_elts[i]<<'\''); 00202 TestTreeNode *next_child = new TestTreeNode(path_elts[i]); 00203 current->add_child(next_child); 00204 current = next_child; 00205 } else { 00206 CPUNIT_DTRACE("TestStore::find_node - returning NULL."); 00207 return NULL; 00208 } 00209 } 00210 CPUNIT_DTRACE("TestStore::find_node - returning '"<<current->get_path()<<'\''); 00211 return current; 00212 } 00213