Fresco/test/syunit-c++/src Breakpoint.cc,NONE,1.1 ResultsMap.cc,NONE,1.1 TestCase.cc,NONE,1.1 TestCaseWrapper.cc,NONE,1.1 TestCmd.cc,NONE,1.1

Nathaniel Smith <[email protected]>
Newsgroups gmane.comp.video.fresco.cvs
Message-ID <[email protected]>
Update of /cvs/fresco/Fresco/test/syunit-c++/src
In directory purcel:/tmp/cvs-serv16654/test/syunit-c++/src

Added Files:
	Breakpoint.cc ResultsMap.cc TestCase.cc TestCaseWrapper.cc 
	TestCmd.cc 
Log Message:
The basic unit test infrastructure... now we just need build
system support...


--- NEW FILE: Breakpoint.cc ---
#include "Breakpoint.hh"

extern "C"
{

  void
  Fresco_Test_fail_breakpoint()
  {
    Fresco_Test_breakpoint();
  }

  void
  Fresco_Test_error_breakpoint()
  {
    Fresco_Test_breakpoint();
  }

  void
  Fresco_Test_breakpoint() {}  
}

--- NEW FILE: ResultsMap.cc ---
#include "ResultsMap.hh"

namespace Fresco_Test
{

const std::string ResultsMap::continuation_indent("   ");
const std::string ResultsMap::blank_line_quote(".");

void
ResultsMap::clear()
{
  my_keys.clear();
  my_map.clear();
}
  
std::string&
ResultsMap::operator [] (const std::string& key)
{
  // Is this really the best way to check whether a map already
  // contains an entry for a given key?
  if (!my_map.count(key))
  {
    my_keys.push_back(std::string(key));
  }
  return my_map[key];
}

bool
ResultsMap::operator == (const ResultsMap& other) const
{
  return my_map == other.my_map;
}

ResultsMap &
ResultsMap::operator = (const ResultsMap& other)
{
  my_keys = other.my_keys;
  my_map = other.my_map;
}

// This might be a bit inefficient, since we print one character at a
// time, but the effect is probably negligible (and the code is
// cleaner and probably faster than my first try that didn't do
// that...)
std::ostream&
operator << (std::ostream& os, ResultsMap rm)
{
  std::list<std::string>::const_iterator i;
  for (i = rm.my_keys.begin(); i != rm.my_keys.end(); i++)
  {
    // "<key>: "
    os << *i << ": ";

    // "<desc>"
    std::string& desc = rm[*i];

    bool seen_chars_this_line = true;
    std::string::iterator j = desc.begin();
    while (j != desc.end())
    {
      if (*j == '\n')
      {
        if (!seen_chars_this_line) os << rm.blank_line_quote;
        seen_chars_this_line = false;
        os << *j;
        j++;
        if (j != desc.end()) os << rm.continuation_indent;
      }
      else
      {
        seen_chars_this_line = true;
        os << *j;
        j++;
      }
    }
    // Add a final \n if necessary
    if (seen_chars_this_line) os << '\n';
  }

  return os;
}
 
}

--- NEW FILE: TestCase.cc ---
#include <sstream>

#include "TestCase.hh"
#include "Breakpoint.hh"
#include "ResultsMap.hh"

namespace Fresco_Test
{

void
TestCase::fail(const std::string msg)
{
  Fresco_Test_fail_breakpoint();
  result["Result"] = "FAIL";
  result["Cause"] = msg;
  throw TestFailure();
}

void
TestCase::error(const std::string msg)
{
  Fresco_Test_error_breakpoint();
  result["Result"] = "ERROR";
  result["Cause"] = msg;
  throw TestError();
}

void
TestCase::assert_true(bool cond,
                      const std::string msg)
{
  if (!cond) fail(msg);
}

void
TestCase::assert_false(bool cond,
                       const std::string msg)
{
  if (cond) fail(msg);
}

void
TestCase::assert_equals_delta(double x, double y, double epsilon,
                              const std::string msg)
{
  if (! (-epsilon < x-y && epsilon > x-y) )
  {
    if (msg != "") fail(msg);
    else
    {
      std::stringstream my_msg;
      my_msg << "assert_equals_delta failed: "
             << x << " - " << y << " = " << x - y
             << "; epsilon was " << epsilon << ".";
      fail(my_msg.str());
    }
  }
}

void
TestCase::assert_equals(float, float, const std::string)
{
  error("Called assert_equals with two float arguments.");
}

void
TestCase::assert_equals(double, double, const std::string)
{
  error("Called assert_equals with two double arguments.");
}

}

--- NEW FILE: TestCaseWrapper.cc ---
#include "ResultsMap.hh"
#include "TestCaseWrapper.hh"
#include "TestCase.hh"
#include "Breakpoint.hh"

namespace Fresco_Test
{


}

--- NEW FILE: TestCmd.cc ---
#include <iostream>

#include "ResultsMap.hh"
#include "TestCmd.hh"
#include "TestCase.hh"

namespace Fresco_Test
{

TestCmd::TestCmd(char argc, char** argv)
  : my_exec_name(argv[0]),
    my_action(INVALID),
    my_test_name(),
    my_tests()
{
  if (argc == 1)
  {
    usage();
    exit(1);
  }
  if (!strcmp(argv[1], "run"))
  {
    my_action = RUN;
    if (argc == 2) my_test_name = "all";
    else if (argc == 3) my_test_name = argv[2];
    else
    {
      std::cerr << "Too many arguments to \"run\".\n";
      usage();
      exit(1);
    }
  }
  else if (!strcmp(argv[1], "list"))
  {
    my_action = LIST;
    if (argc > 2)
    {
      std::cerr << "Too many arguments to \"list\".\n";
      usage();
      exit(1);
    }
  }
  else
  {
    std::cerr << "Unknown command \"" << argv[1] << "\"\n";
    usage();
    exit(1);
  }
}

TestCmd::~TestCmd()
{
  std::map<const std::string, TestCaseWrapper*>::iterator i;
  for (i = my_tests.begin(); i != my_tests.end(); i++)
  {
    delete(i->second);
  }
}

// This takes ownership of the passed in TestCaseWrapper
void
TestCmd::add(TestCaseWrapper* test)
{
  if (!my_tests.count(test->name()))
  {
    my_tests[test->name()] = test;
  }
  else
  {
    std::cerr << "Multiple tests registered under name "
              << test->name() << std::endl;
    exit(1);
  }
}
  
int
TestCmd::run()
{
  std::map<const std::string, TestCaseWrapper*>::iterator i;
  if (my_action == LIST)
  {
    for (i = my_tests.begin(); i != my_tests.end(); i++)
    {
      std::cout << i->first << std::endl;
    }
  }
  else if (my_action == RUN)
  {
    if (my_test_name == "all")
    {
      bool first_time = true;
      for (i = my_tests.begin(); i != my_tests.end(); i++)
      {
        if (first_time)  first_time = false;
        else std::cout << "\n";
        std::cout << i->second->run();
      }
    }
    else
    {
      std::cout << my_tests[my_test_name]->run();
    }
    
  }
  else
  {
    std::cerr << "Can't happen: invalid action in run()\n";
    exit(1);
  }
  return 0;
}

void
TestCmd::usage()
{
  std::cerr << "Usage:" << std::endl
            << "   " << my_exec_name << " list" << std::endl
            << "   " << my_exec_name << " run <test name>" << std::endl
            << "   " << my_exec_name << " run [all]" << std::endl;
}
 
}
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.