Skip to content
Snippets Groups Projects
Code owners
Assign users and groups as approvers for specific file changes. Learn more.
GraphTest.cpp 19.50 KiB
#include "GraphTest.h"

#include "sax/SaxParseInterface.h"
#include "sax/SaxComposeInterface.h"

#include "factory/XmlDataFactory.hpp"
#include "factory/StringDataFactory.hpp"

#define CPPUNIT_ASSERT_EQUAL_INT(a, b) CPPUNIT_ASSERT_EQUAL(a, (int)b)

CPPUNIT_TEST_SUITE_REGISTRATION(GraphTest);

void GraphTest::testCopyConstruct()
{
	testCopyConstruct_impl(graph::REPRESENTATION::ADJACENCY_LIST);
	testCopyConstruct_impl(graph::REPRESENTATION::ADJACENCY_MATRIX);
}

void GraphTest::testEqual()
{
	testEqual_impl(graph::REPRESENTATION::ADJACENCY_LIST);
	testEqual_impl(graph::REPRESENTATION::ADJACENCY_MATRIX);
}

void GraphTest::testXMLParser()
{
	testXMLParser_impl(graph::REPRESENTATION::ADJACENCY_LIST);
	testXMLParser_impl(graph::REPRESENTATION::ADJACENCY_MATRIX);
}

void GraphTest::testStringParser()
{
	testStringParser_impl(graph::REPRESENTATION::ADJACENCY_LIST);
	testStringParser_impl(graph::REPRESENTATION::ADJACENCY_MATRIX);
}

void GraphTest::testAddEdge()
{
	testAddEdge_impl(graph::REPRESENTATION::ADJACENCY_LIST);
	testAddEdge_impl(graph::REPRESENTATION::ADJACENCY_MATRIX);
}

void GraphTest::testRemoveEdge()
{
	testRemoveEdge_impl(graph::REPRESENTATION::ADJACENCY_LIST);
	testRemoveEdge_impl(graph::REPRESENTATION::ADJACENCY_MATRIX);
}

void GraphTest::testAddNode()
{
	testAddNode_impl(graph::REPRESENTATION::ADJACENCY_LIST);
	testAddNode_impl(graph::REPRESENTATION::ADJACENCY_MATRIX);
}

void GraphTest::testRemoveNode()
{
	testRemoveNode_impl(graph::REPRESENTATION::ADJACENCY_LIST);
	testRemoveNode_impl(graph::REPRESENTATION::ADJACENCY_MATRIX);
}

void GraphTest::testNeighborEdges()
{
	testNeighborEdges_impl(graph::REPRESENTATION::ADJACENCY_LIST);
	testNeighborEdges_impl(graph::REPRESENTATION::ADJACENCY_MATRIX);
}

void GraphTest::testHasEdge()
{
	testHasEdge_impl(graph::REPRESENTATION::ADJACENCY_LIST);
	testHasEdge_impl(graph::REPRESENTATION::ADJACENCY_MATRIX);
}

void GraphTest::testCopyConstruct_impl(graph::REPRESENTATION representation)
{
	// Common
	graph::Node n1("n1");
	graph::Node n2("n2");
	graph::Node n3("n3");

	// Directed
	graph::DirectedGraph dg(representation);
	dg.addNode(n1);
	dg.addNode(n2);
	dg.addNode(n3);
	dg.addEdge(graph::DirectedEdge(n1, n2));
	dg.addEdge(graph::DirectedEdge(n1, n3));

	graph::DirectedGraph dg2(dg);
	CPPUNIT_ASSERT(dg == dg2);

	graph::DirectedGraph dg3(std::move(dg));
	CPPUNIT_ASSERT(dg2 == dg3);

	// Undirected
	graph::UndirectedGraph ug(representation);
	ug.addNode(n1);
	ug.addNode(n2);
	ug.addNode(n3);
	ug.addEdge(graph::UndirectedEdge(n1, n2));
	ug.addEdge(graph::UndirectedEdge(n1, n3));

	graph::UndirectedGraph ug2(ug);
	CPPUNIT_ASSERT(ug == ug2);

	graph::UndirectedGraph ug3(std::move(ug));
	CPPUNIT_ASSERT(ug2 == ug3);
}

void GraphTest::testEqual_impl(graph::REPRESENTATION representation)
{
	// Common
	graph::Node n1("n1");
	graph::Node n2("n2");
	graph::Node n3("n3");

	// Directed
	graph::DirectedGraph dg(representation);
	dg.addNode(n1);
	dg.addNode(n2);
	dg.addNode(n3);
	dg.addEdge(graph::DirectedEdge(n1, n2));
	dg.addEdge(graph::DirectedEdge(n1, n3));

	graph::DirectedGraph dg2(representation);
	dg2.addNode(n1);
	dg2.addNode(n2);
	dg2.addEdge(graph::DirectedEdge(n1, n2));

	CPPUNIT_ASSERT(dg != dg2);

	dg2.addNode(n3);
	CPPUNIT_ASSERT(dg != dg2);

	dg2.addEdge(graph::DirectedEdge(n1, n3));
	CPPUNIT_ASSERT(dg == dg2);

	// Undirected
	graph::UndirectedGraph ug(representation);
	ug.addNode(n1);
	ug.addNode(n2);
	ug.addNode(n3);
	ug.addEdge(graph::UndirectedEdge(n1, n2));
	ug.addEdge(graph::UndirectedEdge(n1, n3));

	graph::UndirectedGraph ug2(representation);
	ug2.addNode(n1);
	ug2.addNode(n2);
	ug2.addEdge(graph::UndirectedEdge(n1, n2));

	CPPUNIT_ASSERT(ug != ug2);

	ug2.addNode(n3);
	CPPUNIT_ASSERT(ug != ug2);

	ug2.addEdge(graph::UndirectedEdge(n1, n3));
	CPPUNIT_ASSERT(ug == ug2);
}

void GraphTest::testXMLParser_impl(graph::REPRESENTATION representation)
{
	// Common
	graph::Node n1("n1");
	graph::Node n2("n2");
	graph::Node n3("n3");

	// Directed
	graph::DirectedGraph dg(representation);
	dg.addNode(n1);
	dg.addNode(n2);
	dg.addNode(n3);
	dg.addEdge(graph::DirectedEdge(n1, n2));
	dg.addEdge(graph::DirectedEdge(n1, n3));

	graph::Graph dg1(dg);
	std::string tmp = alib::XmlDataFactory::toString(dg1);
	graph::Graph dg2 = alib::XmlDataFactory::fromString<graph::Graph>(tmp);
	CPPUNIT_ASSERT(dg1 == dg2);

	// Undirected
	graph::UndirectedGraph ug(representation);
	ug.addNode(n1);
	ug.addNode(n2);
	ug.addNode(n3);
	ug.addEdge(graph::UndirectedEdge(n1, n2));
	ug.addEdge(graph::UndirectedEdge(n1, n3));

	graph::Graph ug1(ug);
	tmp = alib::XmlDataFactory::toString(ug1);
	graph::Graph ug2 = alib::XmlDataFactory::fromString<graph::Graph>(tmp);
	CPPUNIT_ASSERT(ug1 == ug2);
}

void GraphTest::testStringParser_impl(graph::REPRESENTATION representation)
{
	// Common
	graph::Node n1("n1");
	graph::Node n2("n2");
	graph::Node n3("n3");

	// Directed
	graph::DirectedGraph dg(representation);
	dg.addNode(n1);
	dg.addNode(n2);
	dg.addNode(n3);
	dg.addEdge(graph::DirectedEdge(n1, n2));
	dg.addEdge(graph::DirectedEdge(n1, n3));

	graph::Graph dg1(dg);
	std::string tmp = alib::StringDataFactory::toString(dg1);
	graph::Graph dg2 = alib::StringDataFactory::fromString<graph::Graph>(tmp);
	CPPUNIT_ASSERT(dg1 == dg2);

	// Undirected
	graph::UndirectedGraph ug(representation);
	ug.addNode(n1);
	ug.addNode(n2);
	ug.addNode(n3);
	ug.addEdge(graph::UndirectedEdge(n1, n2));
	ug.addEdge(graph::UndirectedEdge(n1, n3));

	graph::Graph ug1(ug);
	tmp = alib::StringDataFactory::toString(ug1);
	graph::Graph ug2 = alib::StringDataFactory::fromString<graph::Graph>(tmp);
	CPPUNIT_ASSERT(ug1 == ug2);
}

void GraphTest::testAddEdge_impl(graph::REPRESENTATION representation)
{
	// Common
	graph::Node n1("n1");
	graph::Node n2("n2");
	graph::Node n3("n3");
	graph::Node n4("n4");

	// Directed
	graph::DirectedGraph dg(representation);
	dg.addNode(n1);
	dg.addNode(n2);
	dg.addNode(n3);
	dg.addNode(n4);

	CPPUNIT_ASSERT_EQUAL(true, dg.getEdges().empty());
	CPPUNIT_ASSERT_EQUAL(true, dg.findEdges(n1, n2).empty());

	dg.addEdge(graph::DirectedEdge(n1, n2));
	CPPUNIT_ASSERT_EQUAL_INT(1, dg.getEdges().size());
	CPPUNIT_ASSERT_EQUAL_INT(1, dg.findEdges(n1, n2).size());
	CPPUNIT_ASSERT_EQUAL(true, dg.findEdges(n2, n1).empty());

	// Multi-edge can only be added with non-empty label
	CPPUNIT_ASSERT_EQUAL(false, dg.addEdge(graph::DirectedEdge(n1, n2)));
	CPPUNIT_ASSERT_EQUAL_INT(1, dg.getEdges().size());
	CPPUNIT_ASSERT_EQUAL_INT(1, dg.findEdges(n1, n2).size());
	CPPUNIT_ASSERT_EQUAL(true, dg.findEdges(n2, n1).empty());

	dg.addEdge(graph::DirectedEdge(n2, n3));
	CPPUNIT_ASSERT_EQUAL_INT(2, dg.getEdges().size());
	CPPUNIT_ASSERT_EQUAL_INT(1, dg.findEdges(n2, n3).size());
	CPPUNIT_ASSERT_EQUAL(true, dg.findEdges(n3, n2).empty());

	dg.addEdge(graph::DirectedEdge(n3, n4));
	CPPUNIT_ASSERT_EQUAL_INT(3, dg.getEdges().size());
	CPPUNIT_ASSERT_EQUAL_INT(1, dg.findEdges(n3, n4).size());
	CPPUNIT_ASSERT_EQUAL(true, dg.findEdges(n4, n3).empty());

	// Multi-edge can only be added with non-empty label
	CPPUNIT_ASSERT_EQUAL(false, dg.addEdge(graph::DirectedEdge(n3, n4)));
	CPPUNIT_ASSERT_EQUAL_INT(3, dg.getEdges().size());
	CPPUNIT_ASSERT_EQUAL_INT(1, dg.findEdges(n3, n4).size());
	CPPUNIT_ASSERT_EQUAL(true, dg.findEdges(n4, n3).empty());

	dg.addEdge(graph::DirectedEdge(n3, n4, "multi-edge"));
	CPPUNIT_ASSERT_EQUAL_INT(4, dg.getEdges().size());
	CPPUNIT_ASSERT_EQUAL_INT(2, dg.findEdges(n3, n4).size());
	CPPUNIT_ASSERT_EQUAL(true, dg.findEdges(n4, n3).empty());

	// Undirected
	graph::UndirectedGraph ug(representation);
	ug.addNode(n1);
	ug.addNode(n2);
	ug.addNode(n3);
	ug.addNode(n4);

	CPPUNIT_ASSERT_EQUAL(true, ug.getEdges().empty());
	CPPUNIT_ASSERT_EQUAL(true, ug.findEdges(n1, n2).empty());

	ug.addEdge(graph::UndirectedEdge(n1, n2));
	CPPUNIT_ASSERT_EQUAL_INT(1, ug.getEdges().size());
	CPPUNIT_ASSERT_EQUAL_INT(1, ug.findEdges(n1, n2).size());
	CPPUNIT_ASSERT_EQUAL_INT(1, ug.findEdges(n2, n1).size());

	// Multi-edge can only be added with non-empty label
	CPPUNIT_ASSERT_EQUAL(false, ug.addEdge(graph::UndirectedEdge(n1, n2)));
	CPPUNIT_ASSERT_EQUAL_INT(1, ug.getEdges().size());
	CPPUNIT_ASSERT_EQUAL_INT(1, ug.findEdges(n1, n2).size());
	CPPUNIT_ASSERT_EQUAL_INT(1, ug.findEdges(n2, n1).size());

	ug.addEdge(graph::UndirectedEdge(n2, n3));
	CPPUNIT_ASSERT_EQUAL_INT(2, ug.getEdges().size());
	CPPUNIT_ASSERT_EQUAL_INT(1, ug.findEdges(n2, n3).size());
	CPPUNIT_ASSERT_EQUAL_INT(1, ug.findEdges(n3, n2).size());

	ug.addEdge(graph::UndirectedEdge(n3, n4));
	CPPUNIT_ASSERT_EQUAL_INT(3, ug.getEdges().size());
	CPPUNIT_ASSERT_EQUAL_INT(1, ug.findEdges(n3, n4).size());
	CPPUNIT_ASSERT_EQUAL_INT(1, ug.findEdges(n4, n3).size());

	// Multi-edge can only be added with non-empty label
	CPPUNIT_ASSERT_EQUAL(false, ug.addEdge(graph::UndirectedEdge(n3, n4)));
	CPPUNIT_ASSERT_EQUAL_INT(3, ug.getEdges().size());
	CPPUNIT_ASSERT_EQUAL_INT(1, ug.findEdges(n3, n4).size());
	CPPUNIT_ASSERT_EQUAL_INT(1, ug.findEdges(n4, n3).size());

	ug.addEdge(graph::UndirectedEdge(n3, n4, "multi-edge"));
	CPPUNIT_ASSERT_EQUAL_INT(4, ug.getEdges().size());
	CPPUNIT_ASSERT_EQUAL_INT(2, ug.findEdges(n3, n4).size());
	CPPUNIT_ASSERT_EQUAL_INT(2, ug.findEdges(n4, n3).size());
}

void GraphTest::testRemoveEdge_impl(graph::REPRESENTATION representation)
{
	// Common
	graph::Node n1("n1");
	graph::Node n2("n2");
	graph::Node n3("n3");
	graph::Node n4("n4");

	// Directed
	graph::DirectedGraph dg(representation);
	dg.addEdge(graph::DirectedEdge(n1, n2));
	dg.addEdge(graph::DirectedEdge(n1, n2, "multi-edge"));
	dg.addEdge(graph::DirectedEdge(n2, n3));
	dg.addEdge(graph::DirectedEdge(n3, n4));
	dg.addEdge(graph::DirectedEdge(n4, n1));

	CPPUNIT_ASSERT_EQUAL_INT(4, dg.getNodes().size());
	CPPUNIT_ASSERT_EQUAL_INT(5, dg.getEdges().size());

	CPPUNIT_ASSERT_EQUAL_INT(1, dg.neighbors(n1).size());
	dg.removeEdge(graph::DirectedEdge(n1, n2));
	CPPUNIT_ASSERT_EQUAL_INT(1, dg.findEdges(n1, n2).size());
	CPPUNIT_ASSERT_EQUAL_INT(1, dg.neighbors(n1).size());

	CPPUNIT_ASSERT_EQUAL_INT(1, dg.neighbors(n1).size());
	dg.removeEdge(graph::DirectedEdge(n1, n2, "multi-edge"));
	CPPUNIT_ASSERT_EQUAL_INT(0, dg.findEdges(n1, n2).size());
	CPPUNIT_ASSERT_EQUAL(true, dg.neighbors(n1).empty());

	CPPUNIT_ASSERT_EQUAL_INT(1, dg.neighbors(n2).size());
	dg.removeEdge(graph::DirectedEdge(n2, n3));
	CPPUNIT_ASSERT_EQUAL_INT(0, dg.findEdges(n2, n3).size());
	CPPUNIT_ASSERT_EQUAL(true, dg.neighbors(n2).empty());

	CPPUNIT_ASSERT_EQUAL_INT(1, dg.neighbors(n3).size());
	dg.removeEdge(graph::DirectedEdge(n3, n4));
	CPPUNIT_ASSERT_EQUAL_INT(0, dg.findEdges(n3, n4).size());
	CPPUNIT_ASSERT_EQUAL(true, dg.neighbors(n3).empty());

	CPPUNIT_ASSERT_EQUAL_INT(1, dg.neighbors(n4).size());
	dg.removeEdge(graph::DirectedEdge(n4, n1));
	CPPUNIT_ASSERT_EQUAL_INT(0, dg.findEdges(n4, n1).size());
	CPPUNIT_ASSERT_EQUAL(true, dg.neighbors(n4).empty());

	CPPUNIT_ASSERT_EQUAL(true, dg.getEdges().empty());
	CPPUNIT_ASSERT_EQUAL(true, dg.getNodes().empty());

	// Undirected
	graph::UndirectedGraph ug(representation);
	ug.addEdge(graph::UndirectedEdge(n1, n2));
	ug.addEdge(graph::UndirectedEdge(n1, n2, "multi-edge"));
	ug.addEdge(graph::UndirectedEdge(n2, n3));
	ug.addEdge(graph::UndirectedEdge(n3, n4));
	ug.addEdge(graph::UndirectedEdge(n4, n1));

	CPPUNIT_ASSERT_EQUAL_INT(4, ug.getNodes().size());
	CPPUNIT_ASSERT_EQUAL_INT(5, ug.getEdges().size());

	CPPUNIT_ASSERT_EQUAL_INT(2, ug.neighbors(n1).size());
	ug.removeEdge(graph::UndirectedEdge(n1, n2));
	CPPUNIT_ASSERT_EQUAL_INT(1, ug.findEdges(n1, n2).size());
	CPPUNIT_ASSERT_EQUAL_INT(2, ug.neighbors(n1).size());

	CPPUNIT_ASSERT_EQUAL_INT(2, ug.neighbors(n1).size());
	ug.removeEdge(graph::UndirectedEdge(n1, n2, "multi-edge"));
	CPPUNIT_ASSERT_EQUAL_INT(0, ug.findEdges(n1, n2).size());
	CPPUNIT_ASSERT_EQUAL_INT(1, ug.neighbors(n1).size());

	CPPUNIT_ASSERT_EQUAL_INT(1, ug.neighbors(n2).size());
	ug.removeEdge(graph::UndirectedEdge(n2, n3));
	CPPUNIT_ASSERT_EQUAL_INT(0, ug.findEdges(n2, n3).size());
	CPPUNIT_ASSERT(ug.neighbors(n2).empty());

	CPPUNIT_ASSERT_EQUAL_INT(1, ug.neighbors(n3).size());
	ug.removeEdge(graph::UndirectedEdge(n3, n4));
	CPPUNIT_ASSERT_EQUAL_INT(0, ug.findEdges(n3, n4).size());
	CPPUNIT_ASSERT(ug.neighbors(n3).empty());

	CPPUNIT_ASSERT_EQUAL_INT(1, ug.neighbors(n4).size());
	ug.removeEdge(graph::UndirectedEdge(n4, n1));
	CPPUNIT_ASSERT_EQUAL_INT(0, ug.findEdges(n4, n1).size());
	CPPUNIT_ASSERT_EQUAL(true, ug.neighbors(n4).empty());

	CPPUNIT_ASSERT_EQUAL(true, ug.getEdges().empty());
	CPPUNIT_ASSERT_EQUAL(true, ug.getNodes().empty());
}

void GraphTest::testAddNode_impl(graph::REPRESENTATION representation)
{
	// Directed
	graph::DirectedGraph dg(representation);

	CPPUNIT_ASSERT_EQUAL_INT(0, dg.getNodes().size());
	dg.addNode(graph::Node("n1"));
	CPPUNIT_ASSERT_EQUAL_INT(1, dg.getNodes().size());
	dg.addNode(graph::Node("n2"));
	CPPUNIT_ASSERT_EQUAL_INT(2, dg.getNodes().size());

	CPPUNIT_ASSERT_EQUAL(false, dg.addNode(graph::Node("n2")));
	CPPUNIT_ASSERT_EQUAL_INT(2, dg.getNodes().size());
	dg.addNode(graph::Node("n3"));
	CPPUNIT_ASSERT_EQUAL_INT(3, dg.getNodes().size());
	dg.addNode(graph::Node("n4"));
	CPPUNIT_ASSERT_EQUAL_INT(4, dg.getNodes().size());
	dg.addNode(graph::Node("n5"));
	CPPUNIT_ASSERT_EQUAL_INT(5, dg.getNodes().size());

	// Undirected
	graph::UndirectedGraph ug(representation);

	CPPUNIT_ASSERT_EQUAL_INT(0, ug.getNodes().size());
	ug.addNode(graph::Node("n1"));
	CPPUNIT_ASSERT_EQUAL_INT(1, ug.getNodes().size());
	ug.addNode(graph::Node("n2"));
	CPPUNIT_ASSERT_EQUAL_INT(2, ug.getNodes().size());

	CPPUNIT_ASSERT_EQUAL(false, ug.addNode(graph::Node("n2")));
	CPPUNIT_ASSERT_EQUAL_INT(2, ug.getNodes().size());

	ug.addNode(graph::Node("n3"));
	CPPUNIT_ASSERT_EQUAL_INT(3, ug.getNodes().size());
	ug.addNode(graph::Node("n4"));
	CPPUNIT_ASSERT_EQUAL_INT(4, ug.getNodes().size());
	ug.addNode(graph::Node("n5"));
	CPPUNIT_ASSERT_EQUAL_INT(5, ug.getNodes().size());
}

void GraphTest::testRemoveNode_impl(graph::REPRESENTATION representation)
{
	// Common
	graph::Node n1("n1");
	graph::Node n2("n2");
	graph::Node n3("n3");
	graph::Node n4("n4");

	// Directed
	graph::DirectedGraph dg(representation);
	dg.addEdge(graph::DirectedEdge(n1, n2));
	dg.addEdge(graph::DirectedEdge(n1, n2, "multi-edge"));
	dg.addEdge(graph::DirectedEdge(n2, n3));
	dg.addEdge(graph::DirectedEdge(n3, n4));
	dg.addEdge(graph::DirectedEdge(n4, n1));

	CPPUNIT_ASSERT_EQUAL_INT(4, dg.getNodes().size());
	CPPUNIT_ASSERT_EQUAL_INT(5, dg.getEdges().size());

	dg.removeNode(n1);
	CPPUNIT_ASSERT_EQUAL(true, dg.neighbors(n4).empty());
	CPPUNIT_ASSERT_EQUAL(false, dg.hasEdge(n1, n2));
	CPPUNIT_ASSERT_EQUAL(false, dg.hasEdge(n4, n1));
	CPPUNIT_ASSERT_EQUAL(true, dg.findEdges(n1, n2).empty());
	CPPUNIT_ASSERT_EQUAL(true, dg.findEdges(n4, n1).empty());

	dg.removeNode(n2);
	CPPUNIT_ASSERT_EQUAL(false, dg.hasEdge(n2, n3));
	CPPUNIT_ASSERT_EQUAL(true, dg.findEdges(n2, n3).empty());

	dg.removeNode(n3);
	CPPUNIT_ASSERT_EQUAL(false, dg.hasEdge(n3, n4));
	CPPUNIT_ASSERT_EQUAL(true, dg.findEdges(n3, n4).empty());

	dg.removeNode(n4);
	CPPUNIT_ASSERT_EQUAL(false, dg.hasEdge(n4, n1));
	CPPUNIT_ASSERT_EQUAL(true, dg.findEdges(n4, n1).empty());

	CPPUNIT_ASSERT_EQUAL(true, dg.getEdges().empty());
	CPPUNIT_ASSERT_EQUAL(true, dg.getNodes().empty());

	// Undirected
	graph::UndirectedGraph ug(representation);
	ug.addEdge(graph::UndirectedEdge(n1, n2));
	ug.addEdge(graph::UndirectedEdge(n1, n2, "multi-edge"));
	ug.addEdge(graph::UndirectedEdge(n2, n3));
	ug.addEdge(graph::UndirectedEdge(n3, n4));
	ug.addEdge(graph::UndirectedEdge(n4, n1));

	CPPUNIT_ASSERT_EQUAL_INT(4, ug.getNodes().size());
	CPPUNIT_ASSERT_EQUAL_INT(5, ug.getEdges().size());

	ug.removeNode(n1);
	CPPUNIT_ASSERT_EQUAL_INT(1, ug.neighbors(n4).size());
	CPPUNIT_ASSERT_EQUAL(false, ug.hasEdge(n1, n2));
	CPPUNIT_ASSERT_EQUAL(false, ug.hasEdge(n4, n1));
	CPPUNIT_ASSERT_EQUAL(true, ug.findEdges(n1, n2).empty());
	CPPUNIT_ASSERT_EQUAL(true, ug.findEdges(n4, n1).empty());

	ug.removeNode(n2);
	CPPUNIT_ASSERT_EQUAL(false, ug.hasEdge(n2, n3));
	CPPUNIT_ASSERT_EQUAL(true, ug.findEdges(n2, n3).empty());

	ug.removeNode(n3);
	CPPUNIT_ASSERT_EQUAL(true, ug.neighbors(n4).empty());
	CPPUNIT_ASSERT_EQUAL(false, ug.hasEdge(n3, n4));
	CPPUNIT_ASSERT_EQUAL(true, ug.findEdges(n3, n4).empty());

	ug.removeNode(n4);
	CPPUNIT_ASSERT_EQUAL(false, ug.hasEdge(n4, n1));
	CPPUNIT_ASSERT_EQUAL(true, ug.findEdges(n4, n1).empty());

	CPPUNIT_ASSERT_EQUAL(true, ug.getEdges().empty());
	CPPUNIT_ASSERT_EQUAL(true, ug.getNodes().empty());
}

void GraphTest::testNeighborEdges_impl(graph::REPRESENTATION representation)
{
	// Common
	graph::Node n1("n1");
	graph::Node n2("n2");
	graph::Node n3("n3");
	graph::Node n4("n4");

	// Directed
	graph::DirectedEdge de1(n1, n2);
	graph::DirectedEdge de2(n1, n2, "multi-edge");
	graph::DirectedEdge de3(n1, n3);
	graph::DirectedEdge de4(n2, n3);
	graph::DirectedEdge de5(n3, n4);
	graph::DirectedEdge de6(n4, n1);

	graph::DirectedGraph dg(representation);
	dg.addEdge(de1);
	dg.addEdge(de2);
	dg.addEdge(de3);
	dg.addEdge(de4);
	dg.addEdge(de5);
	dg.addEdge(de6);

	std::set<graph::DirectedEdge> dexpected = { de1, de2, de3 };
	CPPUNIT_ASSERT_EQUAL(dexpected, dg.neighborEdges(n1));

	dexpected = { de4 };
	CPPUNIT_ASSERT_EQUAL(dexpected, dg.neighborEdges(n2));

	dexpected = { de5 };
	CPPUNIT_ASSERT_EQUAL(dexpected, dg.neighborEdges(n3));

	dexpected = { de6 };
	CPPUNIT_ASSERT_EQUAL(dexpected, dg.neighborEdges(n4));

	// Undirected
	graph::UndirectedEdge ue1(n1, n2);
	graph::UndirectedEdge ue2(n1, n2, "multi-edge");
	graph::UndirectedEdge ue3(n1, n3);
	graph::UndirectedEdge ue4(n2, n3);
	graph::UndirectedEdge ue5(n3, n4);
	graph::UndirectedEdge ue6(n4, n1);

	graph::UndirectedGraph ug(representation);
	ug.addEdge(ue1);
	ug.addEdge(ue2);
	ug.addEdge(ue3);
	ug.addEdge(ue4);
	ug.addEdge(ue5);
	ug.addEdge(ue6);

	std::set<graph::UndirectedEdge> uexpected = { ue1, ue2, ue3, ue6 };
	CPPUNIT_ASSERT_EQUAL(uexpected, ug.neighborEdges(n1));

	uexpected = { ue1, ue2, ue4 };
	CPPUNIT_ASSERT_EQUAL(uexpected, ug.neighborEdges(n2));

	uexpected = { ue3, ue4, ue5 };
	CPPUNIT_ASSERT_EQUAL(uexpected, ug.neighborEdges(n3));

	uexpected = { ue5, ue6 };
	CPPUNIT_ASSERT_EQUAL(uexpected, ug.neighborEdges(n4));
}

void GraphTest::testHasEdge_impl(graph::REPRESENTATION representation)
{
	// Common
	graph::Node n1("n1");
	graph::Node n2("n2");
	graph::Node n3("n3");
	graph::Node n4("n4");

	// Directed
	graph::DirectedGraph dg(representation);
	dg.addEdge(graph::DirectedEdge(n1, n2));
	dg.addEdge(graph::DirectedEdge(n1, n2, "multi-edge"));
	dg.addEdge(graph::DirectedEdge(n2, n3));
	dg.addEdge(graph::DirectedEdge(n3, n4));
	dg.addEdge(graph::DirectedEdge(n4, n1));

	CPPUNIT_ASSERT_EQUAL(true, dg.hasEdge(n1, n2));
	CPPUNIT_ASSERT_EQUAL(true, dg.hasEdge(n2, n3));
	CPPUNIT_ASSERT_EQUAL(true, dg.hasEdge(n3, n4));
	CPPUNIT_ASSERT_EQUAL(true, dg.hasEdge(n4, n1));

	CPPUNIT_ASSERT_EQUAL(false, dg.hasEdge(n1, n3));
	CPPUNIT_ASSERT_EQUAL(false, dg.hasEdge(n2, n1));
	CPPUNIT_ASSERT_EQUAL(false, dg.hasEdge(n4, n3));
	CPPUNIT_ASSERT_EQUAL(false, dg.hasEdge(n1, n4));

	// Undirected
	graph::UndirectedGraph ug(representation);
	ug.addEdge(graph::UndirectedEdge(n1, n2));
	ug.addEdge(graph::UndirectedEdge(n1, n2, "multi-edge"));
	ug.addEdge(graph::UndirectedEdge(n2, n3));
	ug.addEdge(graph::UndirectedEdge(n3, n4));
	ug.addEdge(graph::UndirectedEdge(n4, n1));

	CPPUNIT_ASSERT_EQUAL(true, ug.hasEdge(n1, n2));
	CPPUNIT_ASSERT_EQUAL(true, ug.hasEdge(n2, n1));
	CPPUNIT_ASSERT_EQUAL(true, ug.hasEdge(n2, n3));
	CPPUNIT_ASSERT_EQUAL(true, ug.hasEdge(n3, n2));
	CPPUNIT_ASSERT_EQUAL(true, ug.hasEdge(n3, n4));
	CPPUNIT_ASSERT_EQUAL(true, ug.hasEdge(n4, n3));
	CPPUNIT_ASSERT_EQUAL(true, ug.hasEdge(n4, n1));
	CPPUNIT_ASSERT_EQUAL(true, ug.hasEdge(n1, n4));

	CPPUNIT_ASSERT_EQUAL(false, ug.hasEdge(n1, n3));
	CPPUNIT_ASSERT_EQUAL(false, ug.hasEdge(n3, n1));
	CPPUNIT_ASSERT_EQUAL(false, ug.hasEdge(n2, n4));
	CPPUNIT_ASSERT_EQUAL(false, ug.hasEdge(n4, n2));
}