/** @file

    $Id$

    $Date$
    $Author$

    @copy &copy; Marc W&auml;ckerlin
    @license LGPL, see file <a href="license.html">COPYING</a>

         1         2         3         4         5         6         7         8
    5678901234567890123456789012345678901234567890123456789012345678901234567890
*/

#include <mrw/stacktrace.hpp>
#include <cppunit/TestFixture.h>
#include <cppunit/ui/text/TestRunner.h>
#include <cppunit/extensions/HelperMacros.h>
#include <cppunit/extensions/TestFactoryRegistry.h>

namespace mrw {
  class StackTraceTest: public CppUnit::TestFixture { 
  public:
    /// test if symbols are correctely evaluated
    void StackTrace() {
      bool init(mrw::StackTrace::createSymtable());
      CPPUNIT_ASSERT_MESSAGE("createSymtable() failed! ERROR="
                             +mrw::StackTrace::error(),
                             init
                             ||
                             mrw::StackTrace::error().find("/valgrind/")
                             !=std::string::npos);
      mrw::StackTrace s; int l(__LINE__); std::string f(__FILE__);
      std::stringstream ss;
      ss<<f<<':'<<l;
      std::string st(s);
      mrw::StackTrace::BinFiles files(mrw::StackTrace::filename());
      std::string msg("----------------------------------------\n"
                      "Stacktrace:\n-----------\n"+st+
                      "Files:\n------\n");
      for (mrw::StackTrace::BinFiles::iterator it(files.begin());
           it!=files.end(); ++it)
        msg += " - \""+it->first+"\"\n";
      msg += "----------------------------------------\n";
      std::string::size_type pos(st.find("mrw::StackTraceTest::StackTrace()"));
      CPPUNIT_ASSERT_MESSAGE("\"mrw::StackTraceTest::StackTrace()\""
                             " not found!\n"+msg, pos!=std::string::npos);
      CPPUNIT_ASSERT_MESSAGE('"'+ss.str()+"\" not found!\n"+msg,
                             st.find(ss.str(), pos) < st.size());
      CPPUNIT_ASSERT_MESSAGE("\"CppUnit::TestCaller<mrw::StackTraceTest>"
                             "::runTest()\" not found!\n"+msg,
                             st.find("CppUnit::TestCaller<mrw::StackTraceTest>"
                                     "::runTest()")<st.size());
      // The following test case does not work any more!
      // Probable reason: The library has been stripped:
      //     > nm /usr/lib/libcppunit-1.10.so.2.0.0
      //     nm: /usr/lib/libcppunit-1.10.so.2.0.0: no symbols
      //     > file /usr/lib/libcppunit-1.10.so.2.0.0
      //     /usr/lib/libcppunit-1.10.so.2.0.0:
      //         ELF 32-bit LSB shared object, Intel 80386,
      //         version 1 (SYSV), stripped
      //CPPUNIT_ASSERT_MESSAGE("\"CppUnit::TestCase::run\" not found!\n"+msg,
      //                       st.find("CppUnit::TestCase::run")<st.size());
      // The folowing test is probably wrong, because the syntax should be
      // different:
      //   "????                                                   ????:0"
      // Anyway, with the problem of stripped libraries, as above, it doesn't
      // pass anymore, if it is tested correctly...
      //CPPUNIT_ASSERT_MESSAGE("\"????:0 ????\" should not be in stack!\n"+msg,
      //                       st.find("????:0 ????")>=st.size());
    }
    CPPUNIT_TEST_SUITE(StackTraceTest);
    CPPUNIT_TEST(StackTrace);
    CPPUNIT_TEST_SUITE_END();
  };
  CPPUNIT_TEST_SUITE_REGISTRATION(StackTraceTest);
}

int main() {
  CppUnit::TextUi::TestRunner runner;
  runner.addTest(CppUnit::TestFactoryRegistry::getRegistry().makeTest());
  return runner.run() ? 0 : 1;
}
