summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBent Bisballe Nyeng <deva@aasimon.org>2020-06-06 20:42:17 +0200
committerBent Bisballe Nyeng <deva@aasimon.org>2020-06-06 20:42:17 +0200
commit5f95718e7ebe4dec017055500793b928d8946d8e (patch)
tree4f85539d23b2ffb0e35931e1291a107782870ac9
parent540f839cb5868dac3eb409f509b85995826cf559 (diff)
Port existing (in-file embedded) unit-tests to new framework.
-rw-r--r--.gitignore4
-rw-r--r--src/Makefile.am2
-rw-r--r--src/connectionhandler.cc108
-rw-r--r--src/messagehandler.cc18
-rw-r--r--src/messageparser.cc18
-rw-r--r--src/node.cc18
-rw-r--r--src/nodetree.cc51
-rw-r--r--src/saxparser.cc12
-rw-r--r--src/xml_encode_decode.cc21
-rw-r--r--test/Makefile.am37
-rw-r--r--test/connectionhandlertest.cc152
-rw-r--r--test/nodetreetest.cc80
-rw-r--r--test/testclient.cc (renamed from src/testclient.cc)0
-rw-r--r--test/testclient.h (renamed from src/testclient.h)0
-rw-r--r--test/xmlencodetest.cc55
15 files changed, 326 insertions, 250 deletions
diff --git a/.gitignore b/.gitignore
index 6f306be..9ff343f 100644
--- a/.gitignore
+++ b/.gitignore
@@ -13,10 +13,12 @@ depcomp
install-sh
ltmain.sh
missing
+test-driver
.deps/
Makefile
Makefile.in
-src/muniad
+muniad
+muniacli
*.o
*.trs
stamp-h1
diff --git a/src/Makefile.am b/src/Makefile.am
index c942b75..d820912 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -18,7 +18,6 @@ muniad_SOURCES = \
node.cc \
nodemanager.cc \
nodetree.cc \
- testclient.cc \
xml_encode_decode.cc \
xmlparser.cc \
../hugin/hugin.c
@@ -41,7 +40,6 @@ EXTRA_DIST = \
node.h \
nodemanager.h \
nodetree.h \
- testclient.h \
xml_encode_decode.h \
xmlparser.h \
../hugin/hugin.h
diff --git a/src/connectionhandler.cc b/src/connectionhandler.cc
index d0fb9e1..eb0f935 100644
--- a/src/connectionhandler.cc
+++ b/src/connectionhandler.cc
@@ -111,111 +111,3 @@ SubscriberList ConnectionHandler::subscriberlist(NodeIdList nodes)
return clients;
}
-
-
-#ifdef TEST_CONNECTIONHANDLER
-//deps:
-//cflags:
-//libs:
-
-#include "test.h"
-
-TEST_BEGIN;
-
-ConnectionHandler &h = connection_handler;
-
-h.init((clientid_t)1);
-h.subscribe((clientid_t)1, (nodeid_t)1);
-h.subscribe((clientid_t)1, (nodeid_t)2);
-
-h.init((clientid_t)2);
-h.subscribe((clientid_t)2, (nodeid_t)1);
-h.subscribe((clientid_t)2, (nodeid_t)2);
-
-h.init((clientid_t)3);
-h.subscribe((clientid_t)3, (nodeid_t)3);
-
-{
- NodeIdList nodes;
- nodes.push_back((nodeid_t)1);
- SubscriberList clst = h.subscriberlist(nodes);
-
- TEST_TRUE(clst.find((clientid_t)1) != clst.end(), "Got client 1?");
- TEST_TRUE(clst.find((clientid_t)2) != clst.end(), "Got client 2?");
- TEST_FALSE(clst.find((clientid_t)3) != clst.end(), "Got client 3?");
-}
-
-{
- NodeIdList nodes;
- nodes.push_back((nodeid_t)3);
- SubscriberList clst = h.subscriberlist(nodes);
-
- TEST_FALSE(clst.find((clientid_t)1) != clst.end(), "Got client 1?");
- TEST_FALSE(clst.find((clientid_t)2) != clst.end(), "Got client 2?");
- TEST_TRUE(clst.find((clientid_t)3) != clst.end(), "Got client 3?");
-}
-
-{
- NodeIdList nodes;
- nodes.push_back((nodeid_t)4);
- SubscriberList clst = h.subscriberlist(nodes);
-
- TEST_FALSE(clst.find((clientid_t)1) != clst.end(), "Got client 1?");
- TEST_FALSE(clst.find((clientid_t)2) != clst.end(), "Got client 2?");
- TEST_FALSE(clst.find((clientid_t)3) != clst.end(), "Got client 3?");
-}
-
-{
- NodeIdList nodes;
- nodes.push_back((nodeid_t)1);
- nodes.push_back((nodeid_t)2);
- nodes.push_back((nodeid_t)3);
- SubscriberList clst = h.subscriberlist(nodes);
-
- TEST_TRUE(clst.find((clientid_t)1) != clst.end(), "Got client 1?");
- TEST_TRUE(clst.find((clientid_t)2) != clst.end(), "Got client 2?");
- TEST_TRUE(clst.find((clientid_t)3) != clst.end(), "Got client 3?");
-}
-
-h.close((clientid_t)1);
-{
- NodeIdList nodes;
- nodes.push_back((nodeid_t)1);
- nodes.push_back((nodeid_t)2);
- nodes.push_back((nodeid_t)3);
- SubscriberList clst = h.subscriberlist(nodes);
-
- TEST_FALSE(clst.find((clientid_t)1) != clst.end(), "Got client 1?");
- TEST_TRUE(clst.find((clientid_t)2) != clst.end(), "Got client 2?");
- TEST_TRUE(clst.find((clientid_t)3) != clst.end(), "Got client 3?");
-}
-
-h.close((clientid_t)2);
-{
- NodeIdList nodes;
- nodes.push_back((nodeid_t)1);
- nodes.push_back((nodeid_t)2);
- nodes.push_back((nodeid_t)3);
- SubscriberList clst = h.subscriberlist(nodes);
-
- TEST_FALSE(clst.find((clientid_t)1) != clst.end(), "Got client 1?");
- TEST_FALSE(clst.find((clientid_t)2) != clst.end(), "Got client 2?");
- TEST_TRUE(clst.find((clientid_t)3) != clst.end(), "Got client 3?");
-}
-
-h.close((clientid_t)3);
-{
- NodeIdList nodes;
- nodes.push_back((nodeid_t)1);
- nodes.push_back((nodeid_t)2);
- nodes.push_back((nodeid_t)3);
- SubscriberList clst = h.subscriberlist(nodes);
-
- TEST_FALSE(clst.find((clientid_t)1) != clst.end(), "Got client 1?");
- TEST_FALSE(clst.find((clientid_t)2) != clst.end(), "Got client 2?");
- TEST_FALSE(clst.find((clientid_t)3) != clst.end(), "Got client 3?");
-}
-
-TEST_END;
-
-#endif/*TEST_CONNECTIONHANDLER*/
diff --git a/src/messagehandler.cc b/src/messagehandler.cc
index 5467df9..0d536c3 100644
--- a/src/messagehandler.cc
+++ b/src/messagehandler.cc
@@ -214,21 +214,3 @@ MessageList handle_msg(MessageList msgList, clientid_t wsi)
return outmsgs;
}
-
-#ifdef TEST_MSGHANDLER
-//Additional dependency files
-//deps:
-//Required cflags (autoconf vars may be used)
-//cflags:
-//Required link options (autoconf vars may be used)
-//libs:
-#include "test.h"
-
-TEST_BEGIN;
-
-// TODO: Put some testcode here (see test.h for usable macros).
-TEST_TRUE(false, "No tests yet!");
-
-TEST_END;
-
-#endif/*TEST_MSGHANDLER*/
diff --git a/src/messageparser.cc b/src/messageparser.cc
index 82477b7..a5b6d71 100644
--- a/src/messageparser.cc
+++ b/src/messageparser.cc
@@ -399,21 +399,3 @@ message_t create_msg_move(nodeid_t id, nodeid_t to)
m.move.parentid = to;
return m;
}
-
-#ifdef TEST_MSGPARSER
-//Additional dependency files
-//deps:
-//Required cflags (autoconf vars may be used)
-//cflags:
-//Required link options (autoconf vars may be used)
-//libs:
-#include "test.h"
-
-TEST_BEGIN;
-
-// TODO: Put some testcode here (see test.h for usable macros).
-TEST_TRUE(false, "No tests yet!");
-
-TEST_END;
-
-#endif/*TEST_MSGPARSER*/
diff --git a/src/node.cc b/src/node.cc
index 236a511..698c0b1 100644
--- a/src/node.cc
+++ b/src/node.cc
@@ -26,21 +26,3 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
#include "node.h"
-
-#ifdef TEST_NODE
-//Additional dependency files
-//deps:
-//Required cflags (autoconf vars may be used)
-//cflags:
-//Required link options (autoconf vars may be used)
-//libs:
-#include "test.h"
-
-TEST_BEGIN;
-
-// TODO: Put some testcode here (see test.h for usable macros).
-TEST_TRUE(false, "No tests yet!");
-
-TEST_END;
-
-#endif/*TEST_NODE*/
diff --git a/src/nodetree.cc b/src/nodetree.cc
index 1c3992e..2043c90 100644
--- a/src/nodetree.cc
+++ b/src/nodetree.cc
@@ -422,54 +422,3 @@ void NodeTree::fromXML(std::string xml)
XmlParser p(this);
p.parse(xml.c_str(), xml.size());
}
-
-
-#ifdef TEST_NODETREE
-//Additional dependency files
-//deps: debug.cc log.cc
-//Required cflags (autoconf vars may be used)
-//cflags: -I..
-//Required link options (autoconf vars may be used)
-//libs:
-#include "test.h"
-#include <exception>
-
-#define ROOT_ID 0
-#define LOSTFOUND_ID 1
-#define FINISHED_ID 2
-#define BACKLOG_ID 3
-#define PROJECTS_ID 4
-#define FIRST_NODE_ID 10
-
-TEST_BEGIN;
-
-NodeTree tree;
-
-node_t t;
-t.attributes["title"] = "root";
-t.id = ROOT_ID;
-tree.insertAsChild(0, ROOT_ID, t);
-
-t.attributes["title"] = "Finished";
-t.id = FINISHED_ID;
-tree.insertAsChild(ROOT_ID, FINISHED_ID, t);
-
-t.attributes["title"] = "Backlog";
-t.id = BACKLOG_ID;
-tree.insertAsChild(ROOT_ID, BACKLOG_ID, t);
-
-t.attributes["title"] = "Lost+Found";
-t.id = LOSTFOUND_ID;
-tree.insertAsChild(ROOT_ID, LOSTFOUND_ID, t);
-
-t.attributes["title"] = "Projects";
-t.id = PROJECTS_ID;
-tree.insertAsChild(ROOT_ID, PROJECTS_ID, t);
-
-TEST_EQUAL_INT(5, tree.bfs(0).size(), "Testing BFS function");
-TEST_EQUAL_INT(PROJECTS_ID, tree.data(PROJECTS_ID).id, "Testing project id");
-TEST_EQUAL_INT(ROOT_ID, tree.data(ROOT_ID).id, "Testing root id");
-
-TEST_END;
-
-#endif/*TEST_NODETREE*/
diff --git a/src/saxparser.cc b/src/saxparser.cc
index ae0adff..871dc5a 100644
--- a/src/saxparser.cc
+++ b/src/saxparser.cc
@@ -239,15 +239,3 @@ void SAXParser::startTag(std::string, attributes_t &)
void SAXParser::characterData(const std::string &)
{
}
-
-#ifdef TEST_SAXPARSER
-//deps:
-//cflags: -I..
-//libs: -lexpat
-#include <test.h>
-
-TEST_BEGIN;
-
-TEST_END;
-
-#endif/*TEST_SAXPARSER*/
diff --git a/src/xml_encode_decode.cc b/src/xml_encode_decode.cc
index b1777d9..4d56a5f 100644
--- a/src/xml_encode_decode.cc
+++ b/src/xml_encode_decode.cc
@@ -85,24 +85,3 @@ std::string xml_decode(std::string str)
return str;
}
-
-#ifdef TEST_XML_ENCODE_DECODE
-//deps:
-//cflags:
-//libs:
-#include <test.h>
-
-TEST_BEGIN;
-
-std::string in = "&A<B>C\"D\'<>\"&amp;E<>";
-std::string enc = xml_encode(in);
-std::string denc = xml_encode(enc);
-std::string dec = xml_decode(denc);
-std::string ddec = xml_decode(dec);
-
-TEST_EQUAL_STR(in, ddec, "compare");
-TEST_EQUAL_STR(enc, dec, "compare");
-
-TEST_END;
-
-#endif/*TEST_XML_ENCODE_DECODE*/
diff --git a/test/Makefile.am b/test/Makefile.am
index 34b750d..3e962ee 100644
--- a/test/Makefile.am
+++ b/test/Makefile.am
@@ -1,7 +1,7 @@
# Rules for the test code (use `make check` to execute)
if ENABLE_TESTS
-TESTS = logintest
+TESTS = logintest xmlencodetest connectionhandlertest nodetreetest
EXTRA_DIST = \
dgunit.h \
@@ -17,4 +17,39 @@ logintest_SOURCES = \
logintest.cc \
dgtest.cc
+xmlencodetest_CXXFLAGS = -DOUTPUT=\"xmlencodetest\" \
+ $(DEBUG_FLAGS) \
+ -I$(top_srcdir)/src
+xmlencodetest_LDFLAGS =
+xmlencodetest_SOURCES = \
+ $(top_srcdir)/src/xml_encode_decode.cc \
+ xmlencodetest.cc \
+ dgtest.cc
+
+connectionhandlertest_CXXFLAGS = -DOUTPUT=\"connectionhandlertest\" \
+ $(DEBUG_FLAGS) \
+ -I$(top_srcdir)/src \
+ -I$(top_srcdir)/hugin
+connectionhandlertest_LDFLAGS =
+connectionhandlertest_SOURCES = \
+ $(top_srcdir)/hugin/hugin.c \
+ $(top_srcdir)/src/connectionhandler.cc \
+ connectionhandlertest.cc \
+ dgtest.cc
+
+nodetreetest_CXXFLAGS = -DOUTPUT=\"nodetreetest\" \
+ $(DEBUG_FLAGS) \
+ -I$(top_srcdir)/src \
+ -I$(top_srcdir)/hugin \
+ $(EXPAT_CFLAGS)
+nodetreetest_LDFLAGS = $(EXPAT_LIBS)
+nodetreetest_SOURCES = \
+ $(top_srcdir)/hugin/hugin.c \
+ $(top_srcdir)/src/nodetree.cc \
+ $(top_srcdir)/src/xmlparser.cc \
+ $(top_srcdir)/src/saxparser.cc \
+ $(top_srcdir)/src/xml_encode_decode.cc \
+ nodetreetest.cc \
+ dgtest.cc
+
endif
diff --git a/test/connectionhandlertest.cc b/test/connectionhandlertest.cc
new file mode 100644
index 0000000..b35cba4
--- /dev/null
+++ b/test/connectionhandlertest.cc
@@ -0,0 +1,152 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set et sw=2 ts=2: */
+/***************************************************************************
+ * connectionhandlertest.cc
+ *
+ * Sat Jun 6 20:00:25 CEST 2020
+ * Copyright 2020 Bent Bisballe Nyeng
+ * deva@aasimon.org
+ ****************************************************************************/
+
+/*
+ * This file is part of Munia.
+ *
+ * Munia 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 2 of the License, or
+ * (at your option) any later version.
+ *
+ * Munia 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 Munia; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ */
+#include "dgunit.h"
+
+#include <connectionhandler.h>
+
+class ConnectionHandlerTest
+ : public DGUnit
+{
+public:
+ ConnectionHandlerTest()
+ {
+ DGUNIT_TEST(ConnectionHandlerTest::test);
+ }
+
+ bool find_client(const SubscriberList& clst, clientid_t id)
+ {
+ for(const auto& client : clst)
+ {
+ if(client.first == id)
+ {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ void test()
+ {
+ ConnectionHandler &h = connection_handler;
+
+ h.init((clientid_t)1);
+ h.subscribe((clientid_t)1, (nodeid_t)1);
+ h.subscribe((clientid_t)1, (nodeid_t)2);
+
+ h.init((clientid_t)2);
+ h.subscribe((clientid_t)2, (nodeid_t)1);
+ h.subscribe((clientid_t)2, (nodeid_t)2);
+
+ h.init((clientid_t)3);
+ h.subscribe((clientid_t)3, (nodeid_t)3);
+
+ {
+ NodeIdList nodes;
+ nodes.push_back((nodeid_t)1);
+ SubscriberList clst = h.subscriberlist(nodes);
+
+ DGUNIT_ASSERT(find_client(clst, (clientid_t)1)); // Got client 1?
+ DGUNIT_ASSERT(find_client(clst, (clientid_t)2)); // Got client 2?
+ DGUNIT_ASSERT(!find_client(clst, (clientid_t)3)); // Got client 3?
+ }
+
+ {
+ NodeIdList nodes;
+ nodes.push_back((nodeid_t)3);
+ SubscriberList clst = h.subscriberlist(nodes);
+
+ DGUNIT_ASSERT(!find_client(clst, (clientid_t)1)); // Got client 1?
+ DGUNIT_ASSERT(!find_client(clst, (clientid_t)2)); // Got client 2?
+ DGUNIT_ASSERT(find_client(clst, (clientid_t)3)); // Got client 3?
+ }
+
+ {
+ NodeIdList nodes;
+ nodes.push_back((nodeid_t)4);
+ SubscriberList clst = h.subscriberlist(nodes);
+
+ DGUNIT_ASSERT(!find_client(clst, (clientid_t)1)); // Got client 1?
+ DGUNIT_ASSERT(!find_client(clst, (clientid_t)2)); // Got client 2?
+ DGUNIT_ASSERT(!find_client(clst, (clientid_t)3)); // Got client 3?
+ }
+
+ {
+ NodeIdList nodes;
+ nodes.push_back((nodeid_t)1);
+ nodes.push_back((nodeid_t)2);
+ nodes.push_back((nodeid_t)3);
+ SubscriberList clst = h.subscriberlist(nodes);
+
+ DGUNIT_ASSERT(find_client(clst, (clientid_t)1)); // Got client 1?
+ DGUNIT_ASSERT(find_client(clst, (clientid_t)2)); // Got client 2?
+ DGUNIT_ASSERT(find_client(clst, (clientid_t)3)); // Got client 3?
+ }
+
+ h.close((clientid_t)1);
+ {
+ NodeIdList nodes;
+ nodes.push_back((nodeid_t)1);
+ nodes.push_back((nodeid_t)2);
+ nodes.push_back((nodeid_t)3);
+ SubscriberList clst = h.subscriberlist(nodes);
+
+ DGUNIT_ASSERT(!find_client(clst, (clientid_t)1)); // Got client 1?
+ DGUNIT_ASSERT(find_client(clst, (clientid_t)2)); // Got client 2?
+ DGUNIT_ASSERT(find_client(clst, (clientid_t)3)); // Got client 3?
+ }
+
+ h.close((clientid_t)2);
+ {
+ NodeIdList nodes;
+ nodes.push_back((nodeid_t)1);
+ nodes.push_back((nodeid_t)2);
+ nodes.push_back((nodeid_t)3);
+ SubscriberList clst = h.subscriberlist(nodes);
+
+ DGUNIT_ASSERT(!find_client(clst, (clientid_t)1)); // Got client 1?
+ DGUNIT_ASSERT(!find_client(clst, (clientid_t)2)); // Got client 2?
+ DGUNIT_ASSERT(find_client(clst, (clientid_t)3)); // Got client 3?
+ }
+
+ h.close((clientid_t)3);
+ {
+ NodeIdList nodes;
+ nodes.push_back((nodeid_t)1);
+ nodes.push_back((nodeid_t)2);
+ nodes.push_back((nodeid_t)3);
+ SubscriberList clst = h.subscriberlist(nodes);
+
+ DGUNIT_ASSERT(!find_client(clst, (clientid_t)1)); // Got client 1?
+ DGUNIT_ASSERT(!find_client(clst, (clientid_t)2)); // Got client 2?
+ DGUNIT_ASSERT(!find_client(clst, (clientid_t)3)); // Got client 3?
+ }
+ }
+};
+
+// Registers the fixture into the 'registry'
+static ConnectionHandlerTest test;
diff --git a/test/nodetreetest.cc b/test/nodetreetest.cc
new file mode 100644
index 0000000..09d4a7f
--- /dev/null
+++ b/test/nodetreetest.cc
@@ -0,0 +1,80 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set et sw=2 ts=2: */
+/***************************************************************************
+ * nodetreetest.cc
+ *
+ * Sat Jun 6 20:32:48 CEST 2020
+ * Copyright 2020 Bent Bisballe Nyeng
+ * deva@aasimon.org
+ ****************************************************************************/
+
+/*
+ * This file is part of Munia.
+ *
+ * Munia 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 2 of the License, or
+ * (at your option) any later version.
+ *
+ * Munia 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 Munia; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ */
+#include "dgunit.h"
+
+#include <nodetree.h>
+
+#define ROOT_ID 0
+#define LOSTFOUND_ID 1
+#define FINISHED_ID 2
+#define BACKLOG_ID 3
+#define PROJECTS_ID 4
+#define FIRST_NODE_ID 10
+
+class NodeTreeTest
+ : public DGUnit
+{
+public:
+ NodeTreeTest()
+ {
+ DGUNIT_TEST(NodeTreeTest::test);
+ }
+
+ void test()
+ {
+ NodeTree tree;
+
+ node_t t;
+ t.attributes["title"] = "root";
+ t.id = ROOT_ID;
+ tree.insertAsChild(0, ROOT_ID, t);
+
+ t.attributes["title"] = "Finished";
+ t.id = FINISHED_ID;
+ tree.insertAsChild(ROOT_ID, FINISHED_ID, t);
+
+ t.attributes["title"] = "Backlog";
+ t.id = BACKLOG_ID;
+ tree.insertAsChild(ROOT_ID, BACKLOG_ID, t);
+
+ t.attributes["title"] = "Lost+Found";
+ t.id = LOSTFOUND_ID;
+ tree.insertAsChild(ROOT_ID, LOSTFOUND_ID, t);
+
+ t.attributes["title"] = "Projects";
+ t.id = PROJECTS_ID;
+ tree.insertAsChild(ROOT_ID, PROJECTS_ID, t);
+
+ DGUNIT_ASSERT_EQUAL(5, tree.bfs(0).size()); // Testing BFS function
+ DGUNIT_ASSERT_EQUAL(PROJECTS_ID, tree.data(PROJECTS_ID).id); // Testing project id
+ DGUNIT_ASSERT_EQUAL(ROOT_ID, tree.data(ROOT_ID).id); // Testing root id
+ }
+};
+
+// Registers the fixture into the 'registry'
+static NodeTreeTest test;
diff --git a/src/testclient.cc b/test/testclient.cc
index 3bd9d62..3bd9d62 100644
--- a/src/testclient.cc
+++ b/test/testclient.cc
diff --git a/src/testclient.h b/test/testclient.h
index f9562f4..f9562f4 100644
--- a/src/testclient.h
+++ b/test/testclient.h
diff --git a/test/xmlencodetest.cc b/test/xmlencodetest.cc
new file mode 100644
index 0000000..46b515d
--- /dev/null
+++ b/test/xmlencodetest.cc
@@ -0,0 +1,55 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set et sw=2 ts=2: */
+/***************************************************************************
+ * xmlencodetest.cc
+ *
+ * Sat Jun 6 19:54:41 CEST 2020
+ * Copyright 2020 Bent Bisballe Nyeng
+ * deva@aasimon.org
+ ****************************************************************************/
+
+/*
+ * This file is part of Munia.
+ *
+ * Munia 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 2 of the License, or
+ * (at your option) any later version.
+ *
+ * Munia 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 Munia; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ */
+#include "dgunit.h"
+
+#include <xml_encode_decode.h>
+
+class XMLEncodeTest
+ : public DGUnit
+{
+public:
+ XMLEncodeTest()
+ {
+ DGUNIT_TEST(XMLEncodeTest::test);
+ }
+
+ void test()
+ {
+ std::string in = "&A<B>C\"D\'<>\"&amp;E<>";
+ std::string enc = xml_encode(in);
+ std::string denc = xml_encode(enc);
+ std::string dec = xml_decode(denc);
+ std::string ddec = xml_decode(dec);
+
+ DGUNIT_ASSERT_EQUAL(in, ddec);
+ DGUNIT_ASSERT_EQUAL(enc, dec);
+ }
+};
+
+// Registers the fixture into the 'registry'
+static XMLEncodeTest test;