CPUnit 0.95 (beta)
The REAL C++ port of JUnit.
/Users/Shared/Development/cpp/sourceforge/cpunit_095/src/cpunit_TestStore.cpp
Go to the documentation of this file.
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 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Defines