CPUnit 0.7 (beta)
The REAL C++ port of JUnit.
/Users/Shared/Development/cpp/sourceforge/cpunit/src/unittest_TestTreeNode.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 "unittest_AssertionException.hpp"
00033 #include "unittest_WrongSetupException.hpp"
00034 #include "unittest_TestTreeNode.hpp"
00035 #include "unittest_StringFlyweightStore.hpp"
00036 #include "unittest_trace.hpp"
00037 
00038 #include <sstream>
00039 
00040 unittest::TestTreeNode::TestTreeNode(const std::string l_name)
00041   : tests()
00042   , children()
00043   , setUp(NULL)
00044   , tearDown(NULL)
00045   , parent(NULL)
00046   , local_name(StringFlyweightStore::get_instance().intern(l_name))
00047   , counter()
00048 {
00049   UNITTEST_ITRACE("TestTreeNode created - local name: '"<<*local_name<<'\'');
00050 }
00051 
00052 unittest::TestTreeNode::~TestTreeNode() {
00053   TestMap::iterator tit = tests.begin();
00054   while (tit != tests.end()) {
00055     delete tit->second;
00056     tit++;
00057   }
00058 
00059   ChildMap::iterator cit = children.begin();
00060   while (cit != children.end()) {
00061     delete cit->second;
00062     cit++;
00063   }
00064 }
00065 
00066 std::string 
00067 unittest::TestTreeNode::get_path() const {
00068   std::string path("");
00069   if (parent != NULL) {
00070     path = parent->get_path() + "::";
00071   }
00072   path += *local_name;
00073   return path;
00074 }
00075 
00076 std::string 
00077 unittest::TestTreeNode::get_local_name() const {
00078   return *local_name;
00079 }
00080 
00081 void 
00082 unittest::TestTreeNode::register_set_up(Callable *s) {
00083   UNITTEST_DTRACE("TestTreeNode::register_set_up called in '"<<get_path()<<"' with method "<<s->get_reg_info().get_name());
00084   if (setUp != NULL) {
00085     std::stringstream msg;
00086     msg<<"The set up method '"<<s->get_reg_info().to_string()<<"' already exists in the namespace "<<get_path()<<", registered at "<<setUp->get_reg_info().to_string();
00087     throw WrongSetupException(msg.str());
00088   }
00089   setUp = s;
00090 }
00091 
00092 void 
00093 unittest::TestTreeNode::register_tear_down(Callable *t) {
00094   UNITTEST_DTRACE("TestTreeNode::register_tear_down called in '"<<get_path()<<"' with method "<<t->get_reg_info().get_name());
00095   if (tearDown != NULL) {
00096     std::stringstream msg;
00097     msg<<"The tear down method '"<<t->get_reg_info().to_string()<<"' already exists in the namespace, registered at "<<tearDown->get_reg_info().to_string();
00098     throw WrongSetupException(msg.str());
00099   }
00100   tearDown = t;
00101 }
00102 
00103 void 
00104 unittest::TestTreeNode::add_test(Callable *test) {
00105   UNITTEST_DTRACE("TestTreeNode::add_test called in '"<<get_path()<<"' with method "<<test->get_reg_info().get_name());
00106   if(tests.find(test->get_reg_info().get_name()) != tests.end()) {
00107     std::stringstream msg;
00108     msg<<"The test '"<<test->get_reg_info().to_string()<<"' already exists in the namespace, registered at "<<tests.find(test->get_reg_info().get_name())->second->get_reg_info().to_string();
00109     throw WrongSetupException(msg.str());
00110   }
00111   tests.insert(std::make_pair(test->get_reg_info().get_name(), test));
00112 }
00113 
00114 void unittest::TestTreeNode::add_child(TestTreeNode *child) {
00115   if(children.find(child->get_local_name()) != children.end()) {
00116     std::stringstream msg;
00117     msg<<"The namespace '"<<child->get_local_name()<<"' already exists in the namespace "<<get_path();
00118     throw WrongSetupException(msg.str());
00119   }
00120   children.insert(std::make_pair(child->get_local_name(), child));
00121 }
00122 
00123 std::map<std::string, unittest::TestTreeNode*> 
00124 unittest::TestTreeNode::get_children() {
00125   return children;
00126 }
00127 
00128 void 
00129 unittest::TestTreeNode::extract_matches(std::vector<TestUnit>& result, const GlobMatcher& m) {
00130   TestMap::iterator tit = tests.begin();
00131   while (tit != tests.end()) {
00132     std::string full_name = tit->second->get_reg_info().get_path() + "::" + tit->second->get_reg_info().get_name();
00133     UNITTEST_DTRACE("Checking match for '"<<full_name<<'\'');
00134     if (m.matches(full_name)) {
00135       UNITTEST_DTRACE("MATCH!");
00136       result.push_back(TestUnit(setUp, tearDown, tit->second));
00137     }
00138     tit++;
00139   }
00140 
00141   ChildMap::iterator cit = children.begin();
00142   while (cit != children.end()) {
00143     cit->second->extract_matches(result, m);
00144     cit++;
00145   }
00146 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Defines