From 0e5293e2b73c2185b03ba14d9adc2f636b77b361 Mon Sep 17 00:00:00 2001 From: Jan Nieuwenhuizen Date: Sat, 30 Dec 2006 14:24:34 +0100 Subject: [PATCH] Use yaffut rather than boost::test for testing. --- flower/include/yaffut.h | 359 +++++++++++++++++++++++++++++++ flower/test-file.cc | 28 +-- flower/test-std.cc | 149 ++++--------- stepmake/stepmake/test-vars.make | 2 +- 4 files changed, 414 insertions(+), 124 deletions(-) create mode 100644 flower/include/yaffut.h diff --git a/flower/include/yaffut.h b/flower/include/yaffut.h new file mode 100644 index 0000000000..91a3521493 --- /dev/null +++ b/flower/include/yaffut.h @@ -0,0 +1,359 @@ +// Copyright 2006 Rutger E.W. van Beusekom. +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +#ifndef __YAFFUT_H__ +#define __YAFFUT_H__ + +#include + +#include +#include +#include +#include +#include +#include + +#define YAFFUT_STRINGIZE(x) YAFFUT_STRINGIZE_(x) +#define YAFFUT_STRINGIZE_(x) #x + +#define __YAFFUT_AT__ __FILE__ ":" YAFFUT_STRINGIZE(__LINE__)": " +#ifndef __AT__ +#define __AT__ __YAFFUT_AT__ +#endif + +#define YAFFUT_EQUAL(e,a) \ + yaffut::equal (e ,a , __YAFFUT_AT__, "EQUAL(" #e " == " #a ") failed ") +#ifndef EQUAL +#define EQUAL YAFFUT_EQUAL +#endif + +#define YAFFUT_UNEQUAL(e,a) \ + yaffut::unequal (e, a, __YAFFUT_AT__, "UNEQUAL(" #e " != " #a ") failed ") +#ifndef UNEQUAL +#define UNEQUAL YAFFUT_UNEQUAL +#endif + +#define YAFFUT_CHECK(e) \ + yaffut::check (e, __YAFFUT_AT__, "CHECK(" #e ") failed ") +#ifndef CHECK +#define CHECK YAFFUT_CHECK +#endif + +#define YAFFUT_FAIL(s) yaffut::fail (s, __YAFFUT_AT__); +#ifndef FAIL +#define FAIL YAFFUT_FAIL +#endif + +#define YAFFUT_ASSERT_THROW(s, e) \ + try \ + { \ + s; \ + throw yaffut::failure (__YAFFUT_AT__, #s " failed to throw"); \ + } \ + catch(const e&){} +#ifndef ASSERT_THROW +#define ASSERT_THROW YAFFUT_ASSERT_THROW +#endif + +namespace yaffut { + +template +std::string demangle() +{ + size_t sz; + int status; + char* ptr = abi::__cxa_demangle(typeid(T).name(), 0, &sz, &status); + std::string name(ptr ? ptr : "", ptr ? strlen(ptr) : 0); + if(ptr){ free(ptr); } + std::string::size_type pos = name.rfind("::"); + if(pos != std::string::npos) + { + name = name.substr(pos + 2); + } + return name; +} + +struct ITest +{ + virtual ~ITest(){} +}; + +class Factory +{ +public: + typedef ITest* (*Create_t) (); +private: + typedef std::map Tests_t; + Tests_t m_Tests; + size_t m_fail; + size_t m_pass; +private: + Factory(){} + ~Factory(){} + static bool EqualsSuiteName (std::string const &name, std::string const& s) + { + return name.find (':') >= name.length () - 2 + && s.substr (0, name.length ()) == name; + } +public: + static Factory& Instance() + { + static Factory instance; + return instance; + } + void Register(const std::string& name, Create_t create) + { + m_Tests[name] = create; + } + size_t Fail () { return m_fail; } + void List(const std::string& name) + { + for(Tests_t::const_iterator it = m_Tests.begin(); it != m_Tests.end(); ++it) + { + if(name.empty () || it->first == name + || EqualsSuiteName (name, it->first)) + std::cout << it->first << std::endl; + } + } + void Run(const std::string& name) + { + for(Tests_t::const_iterator it = m_Tests.begin(); it != m_Tests.end(); ++it) + { + if("All" == name || it->first == name + || EqualsSuiteName (name, it->first)) + { + try + { + std::cout << std::endl << it->first << ' ' << std::flush; + { + std::auto_ptr test(it->second()); + } + std::cout << "[OK]" << std::flush; + ++m_pass; + } + catch(const std::exception& e) + { + std::cout << "[FAIL]\n" << e.what() << std::flush; + ++m_fail; + } + catch(...) + { + std::cout << "[FAIL]\nunknown exception" << std::flush; + ++m_fail; + } + } + } + } + void Report () + { + const size_t size = m_Tests.size(); + std::cout << std::endl; + std::cout << "[TOTAL](" << m_pass + m_fail << '/' << size << ")" << std::endl; + std::cout << "[OK](" << m_pass << '/' << size << ")" << std::endl; + if (m_fail) + std::cout << "[FAIL](" << m_fail << '/' << size << ")" << std::endl; + } + int Main (int argc, const char* argv[]) + { + if(argc > 1 + && (std::string(argv[1]) == "-h" || std::string(argv[1]) == "--help")) + { + std::cout << "Yaffut - Yet Another Framework For Unit Testing.\n\n" + "Usage: yaffut [OPTION] [Suite:|Suite::Test]...\n\n" + "Options:\n" + " -h, --help show this help\n" + " -l, --list list test cases" << std::endl; + return 0; + } + if(argc > 1 + && (std::string(argv[1]) == "-l" || std::string(argv[1]) == "--list")) + { + Factory::Instance().List(argc > 2 ? argv[2] : ""); + return 0; + } + + const char* all[] = {"All"}; + const char** test = all; + int num = 1; + if(1 < argc) + { + test = argv; + num = argc; + } + + for(int i = 0; i < num; ++i) + { + try + { + Factory::Instance().Run(test[i]); + } + catch(const std::exception& e) + { + std::clog << e.what() << std::endl; + } + } + + Factory::Instance().Report (); + return Factory::Instance().Fail (); + } +}; + +class failure: public std::exception +{ + std::string failure_; +public: + template + failure(const Expected& e, Actual& a, const char* at = "", const char* expr = "") + { + std::ostringstream os; + os << at << expr << "\nexpected: " + << "(" << demangle() << ") " << e + << " != actual: " << "(" << demangle() << ") " << a; + failure_ = os.str(); + } + failure(const char* at = "", const char* expr = "") + { + std::ostringstream os; + os << at << expr; + failure_ = os.str(); + } + virtual ~failure() throw() {} + virtual const char* what() const throw() { return failure_.c_str(); } +}; + +template +struct Registrator +{ + Registrator() + { + Factory::Instance().Register(TestName(), Create); + } + const std::string& TestName() + { + static const std::string name(demangle() + "::" + demangle()); + return name; + } + static ITest* Create() + { + return new Case; + } +}; + +template +struct Test: public ITest, public Suite +{ + static Registrator s_Registrator; + Test() + : Suite() + { + Registrator* r = &s_Registrator; + r = 0; + } + template + void assert_throw(void(T::*mf)(), const char* at) + { + try + { + (dynamic_cast (this)->*mf)(); + throw yaffut::failure (at, "statement failed to throw"); + } + catch(const E&){} + } +}; + +template +Registrator Test::s_Registrator; + +template +void equal(const Expected& e, const Actual& a, const char* at = "", const char* expr = "") +{ + if(e != a) + { + throw failure(e, a, at, expr); + } +} +inline void equal(double e, double a, const char* at = "", const char* expr = "") +{ + double max = std::abs(std::max(e, a)); + max = max < 1.0 ? 1.0 : max; + if(std::abs(e - a) > std::numeric_limits::epsilon() * max) + { + throw failure(e, a, at, expr); + } +} +inline void check(bool b, const char* at = "", const char* expr = "") +{ + if(!b) + { + throw failure(at, expr); + } +} + +template +void unequal(const Expected& e, const Actual& a, const char* at = "", const char* expr = "") +{ + if(e == a) + { + throw failure(e, a, at, expr); + } +} +inline void unequal(double e, double a, const char* at = "", const char* expr = "") +{ + double max = std::abs(std::max(e, a)); + max = max < 1.0 ? 1.0 : max; + if(std::abs(e - a) <= std::numeric_limits::epsilon() * max) + { + throw failure(e, a, at, expr); + } +} + +template +void fail(const T& expr, const char* at = "") +{ + std::ostringstream os; + os << expr; + throw failure(at, os.str().c_str()); +} + +template +void assert_throw(void(*pf)(), const char* at = "") +{ + try + { + (*pf)(); + throw failure (at, " statement failed to throw"); + } + catch(const E&){} +} + +//define catch-all suite +struct Suite {}; + +} + +//and for those who prefer macro obscurity over more typing +#define TEST(Suite, Case)\ + namespace { struct Case: public yaffut::Test{ Case(); }; } \ + template struct yaffut::Test; Case::Case() + +#define FUNC(Case)\ + namespace { struct Case: public yaffut::Test{ Case(); }; } \ + template struct yaffut::Test; Case::Case() + +#ifdef YAFFUT_MAIN + +#include + +int main(int argc, const char* argv[]) +{ + std::cout << "pid(" << getpid() << ")" << std::endl; + return yaffut::Factory::Instance().Main (argc, argv); +}; + +#endif /* YAFFUT_MAIN */ + +#define yaffut_main(argc, argv) yaffut::Factory::Instance().Main (argc, argv) + +#endif diff --git a/flower/test-file.cc b/flower/test-file.cc index 177676f791..3198d16650 100644 --- a/flower/test-file.cc +++ b/flower/test-file.cc @@ -1,46 +1,40 @@ -#define HAVE_BOOST_LAMBDA 1 #include "std-vector.hh" #include #include -#include -#include - using namespace std; -using boost::unit_test::test_suite; #include "file-name.hh" string slashify (string file_name); -// FIXME -//BOOST_AUTO_UNIT_TEST (mingw_slashify) -void mingw_slashify () +#include "yaffut.h" + +// FIXME: split into file-name, file-path unit fixture tests +FUNC (mingw_slashify) { File_name f = string ("foe.ly"); string s = slashify (f.to_string ()); cout << s << endl; - BOOST_CHECK_EQUAL (s, "foe.ly"); + EQUAL ("foe.ly", s); f = string ("/tmp/x.ly"); s = slashify (f.to_string ()); cout << s << endl; - BOOST_CHECK_EQUAL (s, "/tmp/x.ly"); + EQUAL ("/tmp/x.ly", s); f = string ("c:/tmp/x.ly"); s = slashify (f.to_string ()); cout << s << endl; - BOOST_CHECK_EQUAL (s, "c:/tmp/x.ly"); + EQUAL ("c:/tmp/x.ly", s); f = string ("\\tmp\\x.ly"); s = slashify (f.to_string ()); cout << s << endl; - BOOST_CHECK_EQUAL (s, "/tmp/x.ly"); + EQUAL ("/tmp/x.ly", s); } #include "config.hh" #include "file-path.hh" -// FIXME -//BOOST_AUTO_UNIT_TEST (mingw_slashify) -void file_find () +FUNC (file_find) { char const *extensions[] = {"ly", "", 0}; string file = "init"; @@ -52,10 +46,10 @@ void file_find () path.parse_path (string (1, PATHSEP) + ly_dir); string file_name = path.find (file, extensions); cout << file_name << endl; - BOOST_CHECK_EQUAL (file_name.substr (file_name.rfind ('/')), "/init.ly"); + EQUAL (file_name.substr (file_name.rfind ('/')), "/init.ly"); file = "init.ly"; file_name = path.find (file, extensions); cout << file_name << endl; - BOOST_CHECK_EQUAL (file_name, ly_dir + "/init.ly"); + EQUAL (file_name, ly_dir + "/init.ly"); } diff --git a/flower/test-std.cc b/flower/test-std.cc index ed317f7f63..d94dfaa23f 100644 --- a/flower/test-std.cc +++ b/flower/test-std.cc @@ -9,16 +9,14 @@ #include -#include -#include +#define YAFFUT_MAIN +#include "yaffut.h" #if !STD_VECTOR #define vector flower_vector #endif using namespace std; -using boost::unit_test::test_suite; -using namespace boost::unit_test; template void @@ -40,24 +38,24 @@ print (Link_array v) } #endif -BOOST_AUTO_UNIT_TEST (vector_erase) +FUNC (vector_erase) { vector v; v.push_back (0); v.push_back (1); - BOOST_CHECK_EQUAL (v.size (), vsize (2)); + EQUAL (v.size (), vsize (2)); v.erase (v.begin () + 1); - BOOST_CHECK_EQUAL (v.size (), vsize (1)); - BOOST_CHECK_EQUAL (v.back (), 0); + EQUAL (v.size (), vsize (1)); + EQUAL (v.back (), 0); v.push_back (1); - BOOST_CHECK_EQUAL (v.size (), vsize (2)); + EQUAL (v.size (), vsize (2)); v.erase (v.begin () + 0); - BOOST_CHECK_EQUAL (v.size (), vsize (1)); - BOOST_CHECK_EQUAL (v.back (), 1); + EQUAL (v.size (), vsize (1)); + EQUAL (v.back (), 1); } -BOOST_AUTO_UNIT_TEST (vector_slice) +FUNC (vector_slice) { vector v; v.push_back (0); @@ -65,18 +63,18 @@ BOOST_AUTO_UNIT_TEST (vector_slice) v.push_back (2); v.push_back (3); #if VECTOR_SLICE - BOOST_CHECK_EQUAL (v.slice (0, 0).size (), vsize (0)); - BOOST_CHECK_EQUAL (v.slice (0, v.size ()).size (), v.size ()); - BOOST_CHECK_EQUAL (v.slice (1, 2).size (), vsize (1)); + EQUAL (v.slice (0, 0).size (), vsize (0)); + EQUAL (v.slice (0, v.size ()).size (), v.size ()); + EQUAL (v.slice (1, 2).size (), vsize (1)); #else - BOOST_CHECK_EQUAL (vector (v.begin (), v.begin ()).size (), vsize (0)); - BOOST_CHECK_EQUAL (vector (v.begin (), v.end ()).size (), v.size ()); - BOOST_CHECK_EQUAL (vector (v.begin () + 1, v.begin () + 2).size (), + EQUAL (vector (v.begin (), v.begin ()).size (), vsize (0)); + EQUAL (vector (v.begin (), v.end ()).size (), v.size ()); + EQUAL (vector (v.begin () + 1, v.begin () + 2).size (), vsize (1)); #endif } -BOOST_AUTO_UNIT_TEST (vector_sorting) +FUNC (vector_sorting) { vector v; v.push_back (2); @@ -88,12 +86,12 @@ BOOST_AUTO_UNIT_TEST (vector_sorting) //sort (v.begin (), v.end ()); vector_sort (v, less ()); #endif - BOOST_CHECK_EQUAL (v[0], 0); - BOOST_CHECK_EQUAL (v[1], 1); - BOOST_CHECK_EQUAL (v[2], 2); + EQUAL (v[0], 0); + EQUAL (v[1], 1); + EQUAL (v[2], 2); } -BOOST_AUTO_UNIT_TEST (vector_insert) +FUNC (vector_insert) { vector v; v.push_back (0); @@ -102,23 +100,23 @@ BOOST_AUTO_UNIT_TEST (vector_insert) #else v.insert (v.begin (), 1); #endif - BOOST_CHECK_EQUAL (v[0], 1); + EQUAL (v[0], 1); #if VECTOR_INSERT v.insert (2, v.size ()); #else v.insert (v.end (), 2); #endif - BOOST_CHECK_EQUAL (v.back (), 2); + EQUAL (v.back (), 2); vector u; u.insert (u.begin (), v.begin (), v.end ()); - BOOST_CHECK_EQUAL (u.size (), v.size ()); + EQUAL (u.size (), v.size ()); u.clear (); u.insert (u.end (), v.begin (), v.end ()); - BOOST_CHECK_EQUAL (u.size (), v.size ()); + EQUAL (u.size (), v.size ()); u.clear (); } -BOOST_AUTO_UNIT_TEST (parray_concat) +FUNC (parray_concat) { #if !STD_VECTOR Link_array u, v; @@ -132,14 +130,14 @@ BOOST_AUTO_UNIT_TEST (parray_concat) v.push_back (&a[3]); v.push_back (&a[4]); concat (u, v); - BOOST_CHECK_EQUAL (u[0], &a[0]); - BOOST_CHECK_EQUAL (u[1], &a[1]); - BOOST_CHECK_EQUAL (u[2], &a[2]); - BOOST_CHECK_EQUAL (u[3], &a[3]); - BOOST_CHECK_EQUAL (u[4], &a[4]); - BOOST_CHECK_EQUAL (u.size (), vsize (5)); + EQUAL (u[0], &a[0]); + EQUAL (u[1], &a[1]); + EQUAL (u[2], &a[2]); + EQUAL (u[3], &a[3]); + EQUAL (u[4], &a[4]); + EQUAL (u.size (), vsize (5)); concat (u, v); - BOOST_CHECK_EQUAL (u.size (), vsize (7)); + EQUAL (u.size (), vsize (7)); u.clear (); v.clear (); @@ -149,15 +147,15 @@ BOOST_AUTO_UNIT_TEST (parray_concat) v.push_back (&a[3]); v.push_back (&a[4]); concat (u, v); - BOOST_CHECK_EQUAL (u[0], &a[0]); - BOOST_CHECK_EQUAL (u[1], &a[1]); - BOOST_CHECK_EQUAL (u[2], &a[2]); - BOOST_CHECK_EQUAL (u[3], &a[3]); - BOOST_CHECK_EQUAL (u[4], &a[4]); - BOOST_CHECK_EQUAL (u.size (), vsize (5)); + EQUAL (u[0], &a[0]); + EQUAL (u[1], &a[1]); + EQUAL (u[2], &a[2]); + EQUAL (u[3], &a[3]); + EQUAL (u[4], &a[4]); + EQUAL (u.size (), vsize (5)); } -BOOST_AUTO_UNIT_TEST (parray_uniq) +FUNC (parray_uniq) { vector v; v.push_back (0); @@ -165,76 +163,15 @@ BOOST_AUTO_UNIT_TEST (parray_uniq) v.push_back (0); vector_sort (v, less ()); uniq (v); - BOOST_CHECK_EQUAL (v.size (), vsize (2)); + EQUAL (v.size (), vsize (2)); } -BOOST_AUTO_UNIT_TEST (vector_search) +FUNC (vector_search) { vector v; v.push_back (0); v.push_back (1); v.push_back (2); vsize i = binary_search (v, 1, less ()); - BOOST_CHECK_EQUAL (i, vsize (1)); -} - -#if 0 -#include "file-name.hh" -string slashify (string file_name); - -BOOST_AUTO_UNIT_TEST (mingw_slashify) -{ - File_name f = string ("foe.ly"); - string s = slashify (f.to_string ()); - cout << s << endl; - BOOST_CHECK_EQUAL (s, "foe.ly"); - f = string ("/tmp/x.ly"); - s = slashify (f.to_string ()); - cout << s << endl; - BOOST_CHECK_EQUAL (s, "/tmp/x.ly"); - f = string ("c:/tmp/x.ly"); - s = slashify (f.to_string ()); - cout << s << endl; - BOOST_CHECK_EQUAL (s, "c:/tmp/x.ly"); - f = string ("\\tmp\\x.ly"); - s = slashify (f.to_string ()); - cout << s << endl; - BOOST_CHECK_EQUAL (s, "/tmp/x.ly"); -} -#endif - -void mingw_slashify (); -void file_find (); - -#include -#include -#include - -test_suite* -init_unit_test_suite (int, char**) -{ - vsize i = 0; - vsize j = 0; - vector v; - binary_search (v, 1, less (), i, j); - //binary_search_bounds (v, 1, &default_compare, 0, 0); - - //Link_array w; - vector w; - binary_search (w, (char*)1, less (), i, j); - - test_suite *test = BOOST_TEST_SUITE("Flower"); - - - test->add (BOOST_TEST_CASE (vector_erase)); - test->add (BOOST_TEST_CASE (vector_slice)); - test->add (BOOST_TEST_CASE (vector_sorting)); - test->add (BOOST_TEST_CASE (vector_insert)); - test->add (BOOST_TEST_CASE (parray_concat)); - test->add (BOOST_TEST_CASE (parray_uniq)); - test->add (BOOST_TEST_CASE (vector_search)); - test->add (BOOST_TEST_CASE (mingw_slashify)); - test->add (BOOST_TEST_CASE (file_find)); - - return test; + EQUAL (i, vsize (1)); } diff --git a/stepmake/stepmake/test-vars.make b/stepmake/stepmake/test-vars.make index 97a1c6b443..ffd57d480b 100644 --- a/stepmake/stepmake/test-vars.make +++ b/stepmake/stepmake/test-vars.make @@ -4,4 +4,4 @@ O_FILES := $(filter-out $(outdir)/test%, $(O_FILES)) TEST_EXECUTABLE = $(outdir)/test-$(NAME) TEST_MODULE_LIBES =$(addprefix $(outdir)/../, $(addsuffix /$(outbase)/library.a, $(TEST_MODULE_LIBS))) -TEST_LOADLIBES = $(TEST_MODULE_LIBES) $(LOADLIBES) -lboost_unit_test_framework +TEST_LOADLIBES = $(TEST_MODULE_LIBES) $(LOADLIBES) -- 2.39.5