diff --git a/Makefile.am b/Makefile.am
index 416c7170..e46671a1 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -169,7 +169,9 @@ UTIL_FILES = \
string.hpp \
stringid.cpp \
stringid.hpp \
+ tap.cpp \
tap.hpp \
+ tap.ipp \
time.cpp \
time.hpp \
types.hpp \
diff --git a/tap.cpp b/tap.cpp
new file mode 100644
index 00000000..6a4d5ed3
--- /dev/null
+++ b/tap.cpp
@@ -0,0 +1,82 @@
+/*
+ * This file is part of libgim.
+ *
+ * libgim is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU General Public License as published by the Free Software
+ * Foundation, either version 3 of the License, or (at your option) any later
+ * version.
+ *
+ * libgim is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with libgim. If not, see .
+ *
+ * Copyright 2015 Danny Robson
+ */
+
+#include "tap.hpp"
+
+#include "debug.hpp"
+
+#include
+
+using util::TAP::logger;
+
+//-----------------------------------------------------------------------------
+logger::logger ():
+ m_status (EXIT_SUCCESS),
+ m_size (0)
+{ ; }
+
+
+//-----------------------------------------------------------------------------
+logger::~logger ()
+{
+ std::cout << "1.." << m_size << '\n';
+}
+
+
+////////////0//////////////////////////////////////////////////////////////////
+void
+util::TAP::logger::expect (bool test, const std::string &msg)
+{
+ std::cout << (test ? "ok " : "not ok ") << ++m_size << " - " << msg << '\n';
+
+ if (!test)
+ m_status = EXIT_FAILURE;
+}
+
+
+///////////////////////////////////////////////////////////////////////////////
+void
+logger::skip (const std::string &msg)
+{
+ std::cout << "ok " << ++m_size << " - # SKIP " << msg << '\n';
+}
+
+
+//-----------------------------------------------------------------------------
+void
+logger::todo (const std::string &msg)
+{
+ std::cout << "not ok " << ++m_size << " - # TODO " << msg << '\n';
+}
+
+
+//-----------------------------------------------------------------------------
+void
+logger::noop (void)
+{
+ skip ("noop");
+}
+
+
+//-----------------------------------------------------------------------------
+int
+logger::status (void) const
+{
+ return m_status;
+}
diff --git a/tap.hpp b/tap.hpp
index e2622a84..169e8d4f 100644
--- a/tap.hpp
+++ b/tap.hpp
@@ -20,33 +20,51 @@
#ifndef __UTIL_TAP_HPP
#define __UTIL_TAP_HPP
-#include
+#include
+#include
+#include
-#define TAP_PLAN(N) do { \
- std::cout << "1.." << (N) << '\n'; \
-} while (0)
+namespace util { namespace TAP {
+ /// A simple TAP (Test Anything Protocol) test case output
+ class logger {
+ public:
+ enum {
+ PASS,
+ FAIL,
+ SKIP,
+ TODO
+ };
+ logger ();
+ ~logger ();
-#define TAP(OK, MSG) do { \
- std::cout << ((OK) ? "ok - " : "not ok - ") << (MSG) << '\n'; \
-} while (0)
+ void expect (bool, const std::string &msg);
+ template
+ void expect (std::function test, const T&, const U&, const std::string &msg);
-#define TAP_EQ(A,B,MSG) do { \
- const auto &&__tap_eq_a = (A); \
- const auto &&__tap_eq_b = (B); \
- \
- TAP (almost_equal (__tap_eq_a, __tap_eq_b), (MSG)); \
-} while (0)
+ template
+ void expect_eq (const T&, const U&, const std::string &msg = "equality");
+ template
+ void expect_neq (const T&, const U&, const std::string &msg = "inequality");
+ template void expect_gt (const T&, const U&, const std::string &msg = "gt");
+ template void expect_ge (const T&, const U&, const std::string &msg = "ge");
+ template void expect_lt (const T&, const U&, const std::string &msg = "lt");
+ template void expect_le (const T&, const U&, const std::string &msg = "le");
-#define TAP_SKIP(MSG) do { \
- std::cout << "ok # skip " << (MSG) << '\n'; \
-} while (0)
+ void skip (const std::string &msg);
+ void todo (const std::string &msg);
+ void noop (void);
+ int status (void) const;
-#define TAP_BAIL(MSG) do { \
- std::cout << "Bail out! " << (MSG) << '\n'; \
-} while (0)
+ private:
+ int m_status;
+ size_t m_size;
+ };
+} }
+
+#include "tap.ipp"
#endif
diff --git a/tap.ipp b/tap.ipp
new file mode 100644
index 00000000..6025d98b
--- /dev/null
+++ b/tap.ipp
@@ -0,0 +1,83 @@
+/*
+ * This file is part of libgim.
+ *
+ * libgim is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU General Public License as published by the Free Software
+ * Foundation, either version 3 of the License, or (at your option) any later
+ * version.
+ *
+ * libgim is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with libgim. If not, see .
+ *
+ * Copyright 2015 Danny Robson
+ */
+
+#ifdef __UTIL_TAP_IPP
+#error
+#endif
+#define __UTIL_TAP_IPP
+
+#include "maths.hpp"
+
+#include
+#include
+
+//-----------------------------------------------------------------------------
+template
+void
+util::TAP::logger::expect (std::function test,
+ const T &a,
+ const U &b,
+ const std::string &msg)
+{
+ bool success = test (a, b);
+ std::cout << (success ? "ok " : "not ok ") << ++m_size << " - " << msg << '\n';
+
+ if (!success)
+ m_status = EXIT_FAILURE;
+}
+
+//-----------------------------------------------------------------------------
+template
+void
+util::TAP::logger::expect_eq (const T&a, const U &b, const std::string &msg)
+{
+ expect (almost_equal, a, b, msg);
+}
+
+
+//-----------------------------------------------------------------------------
+template
+void
+util::TAP::logger::expect_neq (const T&a, const U &b, const std::string &msg)
+{
+ static const std::function TEST = [] (const T &t, const U &u) -> bool {
+ return !almost_equal (t, u);
+ };
+
+ expect (TEST, a, b, msg);
+}
+
+
+//-----------------------------------------------------------------------------
+#define TAP_TEST(SUFFIX,OP) \
+template \
+void \
+util::TAP::logger::expect_ ## SUFFIX (const T &a, \
+ const U &b, \
+ const std::string &msg) \
+{ \
+ std::cout << ((a OP b) ? "ok " : "not ok ") << ++m_size << " - " << msg << '\n'; \
+}
+
+TAP_TEST(gt, > )
+TAP_TEST(ge, >=)
+TAP_TEST(lt, < )
+TAP_TEST(le, <=)
+
+#undef TAP_TEST
diff --git a/test/polynomial.cpp b/test/polynomial.cpp
index 0401c4a1..576a3d97 100644
--- a/test/polynomial.cpp
+++ b/test/polynomial.cpp
@@ -31,7 +31,7 @@ main (int, char**)
{ "cubic 1 uniq", { 1, -3, 3, -1 }, { 1, nan, nan } },
};
- TAP_PLAN(elems (CUBICS));
+ util::TAP::logger test;
for (auto &i: CUBICS) {
std::array s = util::polynomial::solve<3> (i.coeffs);
@@ -52,7 +52,7 @@ main (int, char**)
ok = false;
}
- TAP (ok, i.name);
+ test.expect (ok, i.name);
}
return 0;