changeset 249:3b4ae8feca1c

Switch to GoogleTest finished #285
author David Demelier <markand@malikania.fr>
date Wed, 01 Oct 2014 14:38:25 +0200
parents d157f4747676
children b686a09fb9c6
files C++/Tests/Directory/CMakeLists.txt C++/Tests/Directory/TestDirectory.cpp C++/Tests/Directory/TestDirectory.h C++/Tests/Directory/main.cpp C++/Tests/DynLib/CMakeLists.txt C++/Tests/DynLib/TestDynLib.cpp C++/Tests/DynLib/TestDynLib.h C++/Tests/DynLib/main.cpp C++/Tests/Hash/CMakeLists.txt C++/Tests/Hash/TestHash.cpp C++/Tests/Hash/TestHash.h C++/Tests/Hash/main.cpp C++/Tests/Luae/CMakeLists.txt C++/Tests/Luae/TestLuae.cpp C++/Tests/Luae/TestLuae.h C++/Tests/Luae/TestLuaeClass.cpp C++/Tests/Luae/TestLuaeClass.h C++/Tests/Luae/main-class.cpp C++/Tests/Luae/main.cpp C++/Tests/Pack/CMakeLists.txt C++/Tests/Pack/TestPack.cpp C++/Tests/Pack/TestPack.h C++/Tests/Pack/main.cpp C++/Tests/Parser/CMakeLists.txt C++/Tests/Parser/TestParser.cpp C++/Tests/Parser/TestParser.h C++/Tests/Parser/main.cpp CMakeLists.txt
diffstat 28 files changed, 1087 insertions(+), 1443 deletions(-) [+]
line wrap: on
line diff
--- a/C++/Tests/Directory/CMakeLists.txt	Wed Oct 01 14:37:42 2014 +0200
+++ b/C++/Tests/Directory/CMakeLists.txt	Wed Oct 01 14:38:25 2014 +0200
@@ -20,8 +20,7 @@
 	SOURCES
 	${code_SOURCE_DIR}/C++/Directory.cpp
 	${code_SOURCE_DIR}/C++/Directory.h
-	TestDirectory.cpp
-	TestDirectory.h
+	main.cpp
 )
 
 define_test(directory "${SOURCES}")
--- a/C++/Tests/Directory/TestDirectory.cpp	Wed Oct 01 14:37:42 2014 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,119 +0,0 @@
-/*
- * TestDirectory.h -- test directory class
- *
- * Copyright (c) 2013, 2014 David Demelier <markand@malikania.fr>
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-#include <cppunit/TextTestRunner.h>
-
-#include <Directory.h>
-
-#include "TestDirectory.h"
-
-void TestDirectory::withDot()
-{
-	try {
-		auto flags = Directory::NotDotDot;
-		Directory directory(".", flags);
-		bool dot(false);
-		bool dotdot(false);
-
-		for (const auto &entry : directory) {
-			if (entry.name == ".")
-				dot = true;
-			if (entry.name == "..")
-				dotdot = true;
-		}
-
-		CPPUNIT_ASSERT_EQUAL(dot, true);
-		CPPUNIT_ASSERT_EQUAL(dotdot, false);
-	} catch (const std::runtime_error &error) {
-		std::cout << "skipping test because: " << error.what() << std::endl;
-	}
-}
-
-void TestDirectory::withDotDot()
-{
-	try {
-		auto flags = Directory::NotDot;
-		Directory directory(".", flags);
-		bool dot(false);
-		bool dotdot(false);
-
-		for (const auto &entry : directory) {
-			if (entry.name == ".")
-				dot = true;
-			if (entry.name == "..")
-				dotdot = true;
-		}
-
-		CPPUNIT_ASSERT_EQUAL(dot, false);
-		CPPUNIT_ASSERT_EQUAL(dotdot, true);
-	} catch (const std::runtime_error &error) {
-		std::cout << "skipping test because: " << error.what() << std::endl;
-	}
-}
-
-void TestDirectory::withBothDots()
-{
-	try {
-		Directory directory(".");
-		bool dot(false);
-		bool dotdot(false);
-
-		for (const auto &entry : directory) {
-			if (entry.name == ".")
-				dot = true;
-			if (entry.name == "..")
-				dotdot = true;
-		}
-
-		CPPUNIT_ASSERT_EQUAL(dot, true);
-		CPPUNIT_ASSERT_EQUAL(dotdot, true);
-	} catch (const std::runtime_error &error) {
-		std::cout << "skipping test because: " << error.what() << std::endl;
-	}
-}
-
-void TestDirectory::withoutDots()
-{
-	try {
-		auto flags = Directory::NotDot | Directory::NotDotDot;
-		Directory directory(".", flags);
-		bool dot(false);
-		bool dotdot(false);
-
-		for (const auto &entry : directory) {
-			if (entry.name == ".")
-				dot = true;
-			if (entry.name == "..")
-				dotdot = true;
-		}
-
-		CPPUNIT_ASSERT_EQUAL(dot, false);
-		CPPUNIT_ASSERT_EQUAL(dotdot, false);
-	} catch (const std::runtime_error &error) {
-		std::cout << "skipping test because: " << error.what() << std::endl;
-	}
-}
-
-int main()
-{
-	CppUnit::TextTestRunner runnerText;
-
-	runnerText.addTest(TestDirectory::suite());
-
-	return runnerText.run("", false) == 1 ? 0 : 1;
-}
\ No newline at end of file
--- a/C++/Tests/Directory/TestDirectory.h	Wed Oct 01 14:37:42 2014 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,41 +0,0 @@
-/*
- * TestDirectory.h -- test directory class
- *
- * Copyright (c) 2013, 2014 David Demelier <markand@malikania.fr>
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-#ifndef _TEST_DIRECTORY_H_
-#define _TEST_DIRECTORY_H_
-
-#include <cppunit/extensions/HelperMacros.h>
-#include <cppunit/TestFixture.h>
-
-class TestDirectory : public CppUnit::TestFixture {
-private:
-	CPPUNIT_TEST_SUITE(TestDirectory);
-	CPPUNIT_TEST(withDot);
-	CPPUNIT_TEST(withDotDot);
-	CPPUNIT_TEST(withBothDots);
-	CPPUNIT_TEST(withoutDots);
-	CPPUNIT_TEST_SUITE_END();
-
-public:
-	void withDot();
-	void withDotDot();
-	void withBothDots();
-	void withoutDots();
-};
-
-#endif // !_TEST_DIRECTORY_H_
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/C++/Tests/Directory/main.cpp	Wed Oct 01 14:38:25 2014 +0200
@@ -0,0 +1,115 @@
+/*
+ * main.cpp -- test directory
+ *
+ * Copyright (c) 2013, 2014 David Demelier <markand@malikania.fr>
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <gtest/gtest.h>
+
+#include <Directory.h>
+
+TEST(Filter, withDot)
+{
+	try {
+		auto flags = Directory::NotDotDot;
+		Directory directory(".", flags);
+		bool dot(false);
+		bool dotdot(false);
+
+		for (const auto &entry : directory) {
+			if (entry.name == ".")
+				dot = true;
+			if (entry.name == "..")
+				dotdot = true;
+		}
+
+		ASSERT_TRUE(dot);
+		ASSERT_FALSE(dotdot);
+	} catch (const std::runtime_error &error) {
+		FAIL() << "skipping test because: " << error.what();
+	}
+}
+
+TEST(Filter, withDotDot)
+{
+	try {
+		auto flags = Directory::NotDot;
+		Directory directory(".", flags);
+		bool dot(false);
+		bool dotdot(false);
+
+		for (const auto &entry : directory) {
+			if (entry.name == ".")
+				dot = true;
+			if (entry.name == "..")
+				dotdot = true;
+		}
+
+		ASSERT_FALSE(dot);
+		ASSERT_TRUE(dotdot);
+	} catch (const std::runtime_error &error) {
+		FAIL() << "skipping test because: " << error.what();
+	}
+}
+
+TEST(Filter, withBothDots)
+{
+	try {
+		Directory directory(".");
+		bool dot(false);
+		bool dotdot(false);
+
+		for (const auto &entry : directory) {
+			if (entry.name == ".")
+				dot = true;
+			if (entry.name == "..")
+				dotdot = true;
+		}
+
+		ASSERT_TRUE(dot);
+		ASSERT_TRUE(dotdot);
+	} catch (const std::runtime_error &error) {
+		FAIL() << "skipping test because: " << error.what();
+	}
+}
+
+TEST(Filter, withoutDots)
+{
+	try {
+		auto flags = Directory::NotDot | Directory::NotDotDot;
+		Directory directory(".", flags);
+		bool dot(false);
+		bool dotdot(false);
+
+		for (const auto &entry : directory) {
+			if (entry.name == ".")
+				dot = true;
+			if (entry.name == "..")
+				dotdot = true;
+		}
+
+		ASSERT_FALSE(dot);
+		ASSERT_FALSE(dotdot);
+	} catch (const std::runtime_error &error) {
+		FAIL() << "skipping test because: " << error.what();
+	}
+}
+
+int main(int argc, char **argv)
+{
+	testing::InitGoogleTest(&argc, argv);
+
+	return RUN_ALL_TESTS();
+}
\ No newline at end of file
--- a/C++/Tests/DynLib/CMakeLists.txt	Wed Oct 01 14:37:42 2014 +0200
+++ b/C++/Tests/DynLib/CMakeLists.txt	Wed Oct 01 14:38:25 2014 +0200
@@ -28,8 +28,7 @@
 	SOURCES
 	${code_SOURCE_DIR}/C++/DynLib.cpp
 	${code_SOURCE_DIR}/C++/DynLib.h
-	TestDynLib.cpp
-	TestDynLib.h
+	main.cpp
 )
 
 define_test(dynlib "${SOURCES}")
--- a/C++/Tests/DynLib/TestDynLib.cpp	Wed Oct 01 14:37:42 2014 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,70 +0,0 @@
-/*
- * TestDynLib.cpp -- test the dynamic library loader
- *
- * Copyright (c) 2013, 2014 David Demelier <markand@malikania.fr>
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-#include <iostream>
-
-#include <cppunit/TextTestRunner.h>
-
-#include <DynLib.h>
-
-#include "TestDynLib.h"
-
-/*
- * NOTE: the EXTENSION is defined by CMake in the form of a string
- * literal containing the appropriate extension for the given system.
- */
-
-void TestDynLib::initialize()
-{
-	try {
-		DynLib library("./Plugin" EXTENSION);
-		Initialize init = library.sym<Initialize>("initialize");
-
-		std::string expected("Hello World");
-		std::string result;
-
-		init(result);
-		
-		CPPUNIT_ASSERT_EQUAL(expected, result);
-	} catch (const std::runtime_error &error) {
-		CPPUNIT_ASSERT_MESSAGE(error.what(), false);
-	} catch (const std::out_of_range &error) {
-		CPPUNIT_ASSERT_MESSAGE(error.what(), false);
-	}
-}
-
-void TestDynLib::absent()
-{
-	try {
-		DynLib library("./Plugin" EXTENSION);
-		library.sym<Initialize>("initialize_typo");
-	} catch (const std::out_of_range &error) {
-		return;
-	}
-
-	CPPUNIT_ASSERT_MESSAGE("Expected a failure but succeed", false);
-}
-
-int main()
-{
-	CppUnit::TextTestRunner runnerText;
-
-	runnerText.addTest(TestDynLib::suite());
-
-	return runnerText.run("", false) == 1 ? 0 : 1;
-}
\ No newline at end of file
--- a/C++/Tests/DynLib/TestDynLib.h	Wed Oct 01 14:37:42 2014 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,41 +0,0 @@
-/*
- * TestDynLib.h -- test the dynamic library loader
- *
- * Copyright (c) 2013, 2014 David Demelier <markand@malikania.fr>
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-#ifndef _TEST_DYNLIB_H_
-#define _TEST_DYNLIB_H_
-
-#include <string>
-
-#include <cppunit/extensions/HelperMacros.h>
-#include <cppunit/TestFixture.h>
-
-class TestDynLib : public CppUnit::TestFixture {
-private:
-	using Initialize	= void (*)(std::string &);
-
-	CPPUNIT_TEST_SUITE(TestDynLib);
-	CPPUNIT_TEST(initialize);
-	CPPUNIT_TEST(absent);
-	CPPUNIT_TEST_SUITE_END();
-
-public:
-	void initialize();
-	void absent();
-};
-
-#endif // !_TEST_DYNLIB_H_
\ No newline at end of file
--- a/C++/Tests/DynLib/main.cpp	Wed Oct 01 14:37:42 2014 +0200
+++ b/C++/Tests/DynLib/main.cpp	Wed Oct 01 14:38:25 2014 +0200
@@ -1,8 +1,68 @@
+/*
+ * TestDynLib.cpp -- test the dynamic library loader
+ *
+ * Copyright (c) 2013, 2014 David Demelier <markand@malikania.fr>
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
 #include <iostream>
 
+#include <gtest/gtest.h>
+
 #include <DynLib.h>
 
-int main(void)
+/*
+ * NOTE: the EXTENSION is defined by CMake in the form of a string
+ * literal containing the appropriate extension for the given system.
+ */
+ 
+using Initialize = void (*)(std::string &s);
+
+TEST(Basic, initialize)
 {
-	return 0;
+	try {
+		DynLib library("./Plugin" EXTENSION);
+		Initialize init = library.sym<Initialize>("initialize");
+
+		std::string expected("Hello World");
+		std::string result;
+
+		init(result);
+		
+		ASSERT_EQ(expected, result);
+	} catch (const std::runtime_error &error) {
+		FAIL() << error.what();
+	} catch (const std::out_of_range &error) {
+		FAIL() << error.what();
+	}
+}
+
+TEST(Basic, absent)
+{
+	try {
+		DynLib library("./Plugin" EXTENSION);
+		library.sym<Initialize>("initialize_typo");
+	} catch (const std::out_of_range &error) {
+		return;
+	}
+
+	FAIL() << "Expected a failure but succeed";
+}
+
+int main(int argc, char **argv)
+{
+	testing::InitGoogleTest(&argc, argv);
+
+	return RUN_ALL_TESTS();
 }
\ No newline at end of file
--- a/C++/Tests/Hash/CMakeLists.txt	Wed Oct 01 14:37:42 2014 +0200
+++ b/C++/Tests/Hash/CMakeLists.txt	Wed Oct 01 14:38:25 2014 +0200
@@ -22,8 +22,7 @@
 	SOURCES
 	${code_SOURCE_DIR}/C++/Hash.cpp
 	${code_SOURCE_DIR}/C++/Hash.h
-	TestHash.cpp
-	TestHash.h
+	main.cpp
 )
 
 define_test(hash "${SOURCES}")
--- a/C++/Tests/Hash/TestHash.cpp	Wed Oct 01 14:37:42 2014 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,68 +0,0 @@
-/*
- * TestHash.cpp -- test the hash cryptographic functions
- *
- * Copyright (c) 2013, 2014 David Demelier <markand@malikania.fr>
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-#include <cppunit/TextTestRunner.h>
-
-#include <Hash.h>
-
-#include "TestHash.h"
-
-/*
- * We test the "Hello World" message in all cryptographic functions.
- */
-
-void TestHash::md5()
-{
-	std::string expected = "b10a8db164e0754105b7a99be72e3fe5";
-	std::string output = Hash::md5("Hello World");
-
-	CPPUNIT_ASSERT_EQUAL(output, expected);
-}
-
-void TestHash::sha1()
-{
-	std::string expected = "0a4d55a8d778e5022fab701977c5d840bbc486d0";
-	std::string output = Hash::sha1("Hello World");
-
-	CPPUNIT_ASSERT_EQUAL(output, expected);
-}
-
-void TestHash::sha256()
-{
-	std::string expected = "a591a6d40bf420404a011733cfb7b190d62c65bf0bcda32b57b277d9ad9f146e";
-	std::string output = Hash::sha256("Hello World");
-
-	CPPUNIT_ASSERT_EQUAL(output, expected);
-}
-
-void TestHash::sha512()
-{
-	std::string expected = "2c74fd17edafd80e8447b0d46741ee243b7eb74dd2149a0ab1b9246fb30382f27e853d8585719e0e67cbda0daa8f51671064615d645ae27acb15bfb1447f459b";
-	std::string output = Hash::sha512("Hello World");
-
-	CPPUNIT_ASSERT_EQUAL(output, expected);
-}
-
-int main()
-{
-	CppUnit::TextTestRunner runnerText;
-
-	runnerText.addTest(TestHash::suite());
-
-	return runnerText.run("", false) == 1 ? 0 : 1;
-}
\ No newline at end of file
--- a/C++/Tests/Hash/TestHash.h	Wed Oct 01 14:37:42 2014 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,41 +0,0 @@
-/*
- * TestHash.h -- test the hash cryptographic functions
- *
- * Copyright (c) 2013, 2014 David Demelier <markand@malikania.fr>
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-#ifndef _TEST_HASH_H_
-#define _TEST_HASH_H_
-
-#include <cppunit/extensions/HelperMacros.h>
-#include <cppunit/TestFixture.h>
-
-class TestHash : public CppUnit::TestFixture {
-private:
-	CPPUNIT_TEST_SUITE(TestHash);
-	CPPUNIT_TEST(md5);
-	CPPUNIT_TEST(sha1);
-	CPPUNIT_TEST(sha256);
-	CPPUNIT_TEST(sha512);
-	CPPUNIT_TEST_SUITE_END();
-
-public:
-	void md5();
-	void sha1();
-	void sha256();
-	void sha512();
-};
-
-#endif // !_TEST_HASH_H_
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/C++/Tests/Hash/main.cpp	Wed Oct 01 14:38:25 2014 +0200
@@ -0,0 +1,64 @@
+/*
+ * main.cpp -- test the hash cryptographic functions
+ *
+ * Copyright (c) 2013, 2014 David Demelier <markand@malikania.fr>
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <gtest/gtest.h>
+
+#include <Hash.h>
+
+/*
+ * We test the "Hello World" message in all cryptographic functions.
+ */
+
+TEST(Hash, md5)
+{
+	std::string expected = "b10a8db164e0754105b7a99be72e3fe5";
+	std::string output = Hash::md5("Hello World");
+
+	ASSERT_EQ(expected, output);
+}
+
+TEST(Hash, sha1)
+{
+	std::string expected = "0a4d55a8d778e5022fab701977c5d840bbc486d0";
+	std::string output = Hash::sha1("Hello World");
+
+	ASSERT_EQ(expected, output);
+}
+
+TEST(Hash, sha256)
+{
+	std::string expected = "a591a6d40bf420404a011733cfb7b190d62c65bf0bcda32b57b277d9ad9f146e";
+	std::string output = Hash::sha256("Hello World");
+
+	ASSERT_EQ(expected, output);
+}
+
+TEST(Hash, sha512)
+{
+	std::string expected = "2c74fd17edafd80e8447b0d46741ee243b7eb74dd2149a0ab1b9246fb30382f27e853d8585719e0e67cbda0daa8f51671064615d645ae27acb15bfb1447f459b";
+	std::string output = Hash::sha512("Hello World");
+
+	ASSERT_EQ(expected, output);
+}
+
+int main(int argc, char **argv)
+{
+	testing::InitGoogleTest(&argc, argv);
+
+	return RUN_ALL_TESTS();
+}
\ No newline at end of file
--- a/C++/Tests/Luae/CMakeLists.txt	Wed Oct 01 14:37:42 2014 +0200
+++ b/C++/Tests/Luae/CMakeLists.txt	Wed Oct 01 14:38:25 2014 +0200
@@ -24,8 +24,7 @@
 	${code_SOURCE_DIR}/C++/Luae.h
 	${code_SOURCE_DIR}/C++/LuaeState.cpp
 	${code_SOURCE_DIR}/C++/LuaeState.h
-	TestLuae.cpp
-	TestLuae.h
+	main.cpp
 )
 
 set(
@@ -36,8 +35,7 @@
 	${code_SOURCE_DIR}/C++/LuaeClass.h
 	${code_SOURCE_DIR}/C++/LuaeState.cpp
 	${code_SOURCE_DIR}/C++/LuaeState.h
-	TestLuaeClass.cpp
-	TestLuaeClass.h
+	main-class.cpp
 )
 
 define_test(luae "${LUAE_SOURCES}")
--- a/C++/Tests/Luae/TestLuae.cpp	Wed Oct 01 14:37:42 2014 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,492 +0,0 @@
-/*
- * TestLuae.cpp -- test the Luae class
- *
- * Copyright (c) 2013, 2014 David Demelier <markand@malikania.fr>
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-#include <cppunit/TextTestRunner.h>
-
-#include <Luae.h>
-#include <LuaeState.h>
-
-#include "TestLuae.h"
-
-/* --------------------------------------------------------
- * Custom type Point
- * -------------------------------------------------------- */
-
-struct Point {
-	int x;
-	int y;
-};
-
-template <>
-struct Luae::TypeInfo<Point> : Luae::TypeCustom {
-	static void push(lua_State *L, const Point &point)
-	{
-		lua_createtable(L, 0, 0);
-		lua_pushinteger(L, point.x);
-		lua_setfield(L, -2, "x");
-		lua_pushinteger(L, point.y);
-		lua_setfield(L, -2, "y");
-	}
-
-	static Point get(lua_State *L, int index)
-	{
-		Point p{0, 0};
-
-		if (lua_type(L, index) == LUA_TTABLE) {
-			lua_getfield(L, index, "x");
-			p.x = luaL_optint(L, -1, 0);
-			lua_pop(L, 1);
-			lua_getfield(L, index, "y");
-			p.y = luaL_optint(L, -1, 0);
-			lua_pop(L, 1);
-		}
-
-		return p;
-	}
-
-	static Point check(lua_State *L, int index)
-	{
-		luaL_checktype(L, index, LUA_TTABLE);
-
-		return get(L, index);
-	}
-};
-
-/* --------------------------------------------------------
- * Userdata type Object
- * -------------------------------------------------------- */
-
-struct Object {
-	std::string hello()
-	{
-		return "hello";
-	}
-};
-
-template <>
-struct Luae::TypeInfo<Object> : Luae::TypeUserdata {
-	static constexpr const char *name = "Object";
-};
-
-int l_hello(lua_State *L)
-{
-	return Luae::push(L, Luae::check<Object>(L, 1)->hello());
-}
-
-const Luae::Reg methods {
-	{ "hello",	l_hello		}
-};
-
-/* --------------------------------------------------------
- * Userdata as shared_ptr Widget
- * -------------------------------------------------------- */
-
-class Widget {
-private:
-	int		m_width;
-	int		m_height;
-	std::string	m_name;
-
-public:
-	Widget(int width, int height, const std::string &name)
-		: m_width(width)
-		, m_height(height)
-		, m_name(name)
-	{
-	}
-
-	int width() const
-	{
-		return m_width;
-	}
-
-	int height() const
-	{
-		return m_height;
-	}
-
-	const std::string &name() const
-	{
-		return m_name;
-	}
-};
-
-using WidgetPtr	= std::shared_ptr<Widget>;
-
-template <>
-struct Luae::TypeInfo<Widget> : Luae::TypeUserdata {
-	static constexpr const char *name = "Widget";
-};
-
-int l_width(lua_State *L)
-{
-	return Luae::push(L, Luae::check<WidgetPtr>(L, 1)->width());
-}
-
-int l_height(lua_State *L)
-{
-	return Luae::push(L, Luae::check<WidgetPtr>(L, 1)->height());
-}
-
-int l_name(lua_State *L)
-{
-	return Luae::push(L, Luae::check<WidgetPtr>(L, 1)->name());
-}
-
-const Luae::Reg widgetMethods {
-	{ "width",		l_width		},
-	{ "height",		l_height	},
-	{ "name",		l_name		}
-};
-
-/* --------------------------------------------------------
- * Push function tests
- * -------------------------------------------------------- */
-
-void TestLuae::pushPoint()
-{
-	LuaeState L;
-	Luae::openlibs(L);
-
-	try {
-		Luae::dofile(L, "push.lua");
-		Luae::getglobal(L, "pushPoint");
-		Luae::push(L, Point{10, 20});
-		Luae::pcall(L, 1, 0);
-	} catch (const std::runtime_error &error) {
-		CPPUNIT_ASSERT_MESSAGE("unexpected exception: " + std::string(error.what()), false);
-	}
-}
-
-void TestLuae::pushObject()
-{
-	LuaeState L;
-	Luae::openlibs(L);
-
-	// Object metatable
-	Luae::newmetatable(L, "Object");
-	Luae::newlib(L, methods);
-	Luae::setfield(L, -2, "__index");
-	Luae::pop(L);
-
-	try {
-		Luae::dofile(L, "push.lua");
-		Luae::getglobal(L, "pushObject");
-		Luae::push(L, Object());
-		Luae::pcall(L, 1, 0);
-	} catch (const std::runtime_error &error) {
-		CPPUNIT_ASSERT_MESSAGE("unexpected exception: " + std::string(error.what()), false);
-	}
-}
-
-void TestLuae::pushShared()
-{
-	LuaeState L;
-	Luae::openlibs(L);
-
-	// Widget metatable
-	Luae::newmetatable(L, "Widget");
-	Luae::newlib(L, widgetMethods);
-	Luae::setfield(L, -2, "__index");
-	Luae::pop(L);
-
-	try {
-		Luae::dofile(L, "push.lua");
-		Luae::getglobal(L, "pushShared");
-		Luae::push(L, std::make_shared<Widget>(100, 200, "Button"));
-		Luae::pcall(L, 1, 0);
-	} catch (const std::runtime_error &error) {
-		CPPUNIT_ASSERT_MESSAGE("unexpected exception: " + std::string(error.what()), false);
-	}
-}
-
-void TestLuae::pushSharedTwice()
-{
-	LuaeState L;
-	Luae::openlibs(L);
-
-	// Widget metatable
-	Luae::newmetatable(L, "Widget");
-	Luae::newlib(L, widgetMethods);
-	Luae::setfield(L, -2, "__index");
-	Luae::pop(L);
-
-	try {
-		auto widget = std::make_shared<Widget>(640, 480, "Screen");
-
-		Luae::dofile(L, "push.lua");
-		Luae::getglobal(L, "pushSharedTwice");
-		Luae::push(L, widget);
-		Luae::push(L, widget);
-		Luae::pcall(L, 2, 0);
-	} catch (const std::runtime_error &error) {
-		CPPUNIT_ASSERT_MESSAGE("unexpected exception: " + std::string(error.what()), false);
-	}
-}
-
-/* --------------------------------------------------------
- * Other functions
- * -------------------------------------------------------- */
-
-void TestLuae::preload()
-{
-	LuaeState L;
-	Luae::openlibs(L);
-
-	Luae::preload(L, "luae", [] (lua_State *L) -> int {
-		lua_createtable(L, 0, 0);
-		lua_pushstring(L, "1.0");
-		lua_setfield(L, -2, "version");
-		lua_pushstring(L, "Luae");
-		lua_setfield(L, -2, "name");
-
-		return 1;
-	});
-
-	try {
-		Luae::dofile(L, "loading.lua");
-		Luae::getglobal(L, "test");
-	} catch (const std::runtime_error &error) {
-		CPPUNIT_ASSERT_MESSAGE("unexpected exception: " + std::string(error.what()), false);
-	}
-}
-
-void TestLuae::require()
-{
-	LuaeState L;
-	Luae::openlibs(L);
-
-	Luae::require(L, "luae", [] (lua_State *L) -> int {
-		lua_createtable(L, 0, 0);
-		lua_pushstring(L, "1.0");
-		lua_setfield(L, -2, "version");
-		lua_pushstring(L, "Luae");
-		lua_setfield(L, -2, "name");
-
-		return 1;
-	});
-
-	try {
-		Luae::dofile(L, "loading.lua");
-		Luae::getglobal(L, "test");
-	} catch (const std::runtime_error &error) {
-		CPPUNIT_ASSERT_MESSAGE("unexpected exception: " + std::string(error.what()), false);
-	}
-}
-
-/* --------------------------------------------------------
- * Standard types push / get / check
- * -------------------------------------------------------- */
-
-void TestLuae::testbool()
-{
-	LuaeState L;
-	Luae::openlibs(L);
-
-	try {
-		Luae::dofile(L, "standard.lua");
-		Luae::getglobal(L, "testbool");
-		Luae::push(L, true);
-		Luae::pcall(L, 1, 1);
-		CPPUNIT_ASSERT_EQUAL(Luae::check<bool>(L, 1), false);
-	} catch (const std::runtime_error &error) {
-		CPPUNIT_ASSERT_MESSAGE("unexpected exception: " + std::string(error.what()), false);
-	}
-}
-
-void TestLuae::testdouble()
-{
-	LuaeState L;
-	Luae::openlibs(L);
-
-	try {
-		Luae::dofile(L, "standard.lua");
-		Luae::getglobal(L, "testdouble");
-		Luae::push(L, 10.0);
-		Luae::pcall(L, 1, 1);
-		CPPUNIT_ASSERT_EQUAL(Luae::check<double>(L, 1), -10.0);
-	} catch (const std::runtime_error &error) {
-		CPPUNIT_ASSERT_MESSAGE("unexpected exception: " + std::string(error.what()), false);
-	}
-}
-
-void TestLuae::testint()
-{
-	LuaeState L;
-	Luae::openlibs(L);
-
-	try {
-		Luae::dofile(L, "standard.lua");
-		Luae::getglobal(L, "testint");
-		Luae::push(L, 123);
-		Luae::pcall(L, 1, 1);
-		CPPUNIT_ASSERT_EQUAL(Luae::check<int>(L, 1), -123);
-	} catch (const std::runtime_error &error) {
-		CPPUNIT_ASSERT_MESSAGE("unexpected exception: " + std::string(error.what()), false);
-	}
-}
-
-void TestLuae::testlong()
-{
-	LuaeState L;
-	Luae::openlibs(L);
-
-	try {
-		Luae::dofile(L, "standard.lua");
-		Luae::getglobal(L, "testlong");
-		Luae::push(L, 9999L);
-		Luae::pcall(L, 1, 1);
-		CPPUNIT_ASSERT_EQUAL(Luae::check<long>(L, 1), -9999L);
-	} catch (const std::runtime_error &error) {
-		CPPUNIT_ASSERT_MESSAGE("unexpected exception: " + std::string(error.what()), false);
-	}
-}
-
-void TestLuae::testnil()
-{
-	LuaeState L;
-	Luae::openlibs(L);
-
-	try {
-		Luae::dofile(L, "standard.lua");
-		Luae::getglobal(L, "testnil");
-		Luae::push(L, nullptr);
-		Luae::pcall(L, 1, 1);
-		CPPUNIT_ASSERT_EQUAL(Luae::type(L, -1), LUA_TNIL);
-	} catch (const std::runtime_error &error) {
-		CPPUNIT_ASSERT_MESSAGE("unexpected exception: " + std::string(error.what()), false);
-	}
-}
-
-void TestLuae::teststring()
-{
-	LuaeState L;
-	Luae::openlibs(L);
-
-	try {
-		Luae::dofile(L, "standard.lua");
-		Luae::getglobal(L, "teststring");
-		Luae::push(L, "Hello");
-		Luae::pcall(L, 1, 1);
-		CPPUNIT_ASSERT_EQUAL(Luae::check<std::string>(L, 1), std::string("olleH"));
-	} catch (const std::runtime_error &error) {
-		CPPUNIT_ASSERT_MESSAGE("unexpected exception: " + std::string(error.what()), false);
-	}
-}
-
-void TestLuae::testustring()
-{
-	LuaeState L;
-	Luae::openlibs(L);
-
-	try {
-		std::u32string arg{'H', 'e', 'l', 'l', 'o'};
-		std::u32string expected{'o', 'l', 'l', 'e', 'H'};
-
-		Luae::dofile(L, "standard.lua");
-		Luae::getglobal(L, "testustring");
-		Luae::push(L, arg);
-		Luae::pcall(L, 1, 1);
-		CPPUNIT_ASSERT_MESSAGE("u32string failure", Luae::check<std::u32string>(L, 1) == expected);
-	} catch (const std::runtime_error &error) {
-		CPPUNIT_ASSERT_MESSAGE("unexpected exception: " + std::string(error.what()), false);
-	}
-}
-
-void TestLuae::optionalbool()
-{
-	LuaeState L;
-	Luae::openlibs(L);
-
-	Luae::push(L, nullptr);
-	CPPUNIT_ASSERT_MESSAGE("false expected", Luae::optional<bool>(L, -1, false) == false);
-
-	Luae::push(L, true);
-	CPPUNIT_ASSERT_MESSAGE("true expected", Luae::optional<bool>(L, -1, false) == true);
-}
-
-void TestLuae::optionalint()
-{
-	LuaeState L;
-	Luae::openlibs(L);
-
-	Luae::push(L, nullptr);
-	CPPUNIT_ASSERT_MESSAGE("123 expected", Luae::optional<int>(L, -1, 123) == 123);
-
-	Luae::push(L, 456);
-	CPPUNIT_ASSERT_MESSAGE("456 expected", Luae::optional<int>(L, -1, 999) == 456);
-}
-
-void TestLuae::optionallong()
-{
-	LuaeState L;
-	Luae::openlibs(L);
-
-	Luae::push(L, nullptr);
-	CPPUNIT_ASSERT_MESSAGE("123456789 expected", Luae::optional<long>(L, -1, 123456789) == 123456789);
-
-	Luae::push(L, 789);
-	CPPUNIT_ASSERT_MESSAGE("789 expected", Luae::optional<long>(L, -1, 888) == 789);
-}
-
-void TestLuae::optionaldouble()
-{
-	LuaeState L;
-	Luae::openlibs(L);
-
-	Luae::push(L, nullptr);
-	CPPUNIT_ASSERT_MESSAGE("123.321 expected", Luae::optional<double>(L, -1, 123.321) == 123.321);
-
-	Luae::push(L, 99.44);
-	CPPUNIT_ASSERT_MESSAGE("99.44 expected", Luae::optional<double>(L, -1, 321.321) == 99.44);
-}
-
-void TestLuae::optionalstring()
-{
-	LuaeState L;
-	Luae::openlibs(L);
-
-	Luae::push(L, nullptr);
-	CPPUNIT_ASSERT_MESSAGE("abc expected", Luae::optional<std::string>(L, -1, "abc") == std::string("abc"));
-
-	Luae::push(L, "xyz");
-	CPPUNIT_ASSERT_MESSAGE("xyz expected", Luae::optional<std::string>(L, -1, "qwerty") == std::string("xyz"));
-}
-
-void TestLuae::optionalustring()
-{
-	LuaeState L;
-	Luae::openlibs(L);
-
-	std::u32string expected { 'a', 'b', 'c' };
-	Luae::push(L, nullptr);
-	CPPUNIT_ASSERT_MESSAGE("abc expected", Luae::optional<std::u32string>(L, -1, expected) == expected);
-
-	std::u32string notthatone { 'x', 'y' };
-	Luae::push(L, expected);
-	CPPUNIT_ASSERT_MESSAGE("abc expected", Luae::optional<std::u32string>(L, -1, notthatone) == expected);
-}
-
-int main()
-{
-	CppUnit::TextTestRunner runnerText;
-
-	runnerText.addTest(TestLuae::suite());
-
-	return runnerText.run("", false) == 1 ? 0 : 1;
-}
--- a/C++/Tests/Luae/TestLuae.h	Wed Oct 01 14:37:42 2014 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,71 +0,0 @@
-/*
- * TestLuae.h -- test the Luae class
- *
- * Copyright (c) 2013, 2014 David Demelier <markand@malikania.fr>
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-#ifndef _TEST_LUAE_H_
-#define _TEST_LUAE_H_
-
-#include <cppunit/extensions/HelperMacros.h>
-#include <cppunit/TestFixture.h>
-
-class TestLuae : public CppUnit::TestFixture {
-private:
-	CPPUNIT_TEST_SUITE(TestLuae);
-	CPPUNIT_TEST(pushPoint);
-	CPPUNIT_TEST(pushObject);
-	CPPUNIT_TEST(pushShared);
-	CPPUNIT_TEST(pushSharedTwice);
-	CPPUNIT_TEST(preload);
-	CPPUNIT_TEST(require);
-	CPPUNIT_TEST(testnil);
-	CPPUNIT_TEST(testbool);
-	CPPUNIT_TEST(testint);
-	CPPUNIT_TEST(testlong);
-	CPPUNIT_TEST(testdouble);
-	CPPUNIT_TEST(teststring);
-	CPPUNIT_TEST(testustring);
-	CPPUNIT_TEST(optionalbool);
-	CPPUNIT_TEST(optionalint);
-	CPPUNIT_TEST(optionallong);
-	CPPUNIT_TEST(optionaldouble);
-	CPPUNIT_TEST(optionalstring);
-	CPPUNIT_TEST(optionalustring);
-	CPPUNIT_TEST_SUITE_END();
-
-public:
-	void pushPoint();
-	void pushObject();
-	void pushShared();
-	void pushSharedTwice();
-	void preload();
-	void require();
-	void testnil();
-	void testbool();
-	void testint();
-	void testlong();
-	void testdouble();
-	void teststring();
-	void testustring();
-	void optionalbool();
-	void optionalint();
-	void optionallong();
-	void optionaldouble();
-	void optionalstring();
-	void optionalustring();
-};
-
-#endif // !_TEST_LUAE_H_
--- a/C++/Tests/Luae/TestLuaeClass.cpp	Wed Oct 01 14:37:42 2014 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,183 +0,0 @@
-/*
- * TestLuaeClass.cpp -- test the LuaeClass class
- *
- * Copyright (c) 2013, 2014 David Demelier <markand@malikania.fr>
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-#include <cppunit/TextTestRunner.h>
-
-#include <Luae.h>
-#include <LuaeClass.h>
-#include <LuaeState.h>
-
-#include "TestLuaeClass.h"
-
-/* ---------------------------------------------------------
- * Fake class for TestLuaeClass::create()
- * --------------------------------------------------------- */
-
-class Object {};
-
-template <>
-struct Luae::TypeInfo<Object> : public Luae::TypeUserdata {
-	static constexpr const char *name = "Object";
-};
-
-/* ---------------------------------------------------------
- * Fake classes for TestLuaeClass::testInheritance()
- * --------------------------------------------------------- */
-
-class Base {};
-class Child {};
-
-template <>
-struct Luae::TypeInfo<Base> : public Luae::TypeUserdata {
-	static constexpr const char *name = "Base";
-};
-
-template <>
-struct Luae::TypeInfo<Child> : public Luae::TypeUserdata {
-	static constexpr const char *name = "Child";
-};
-
-void TestLuaeClass::create()
-{
-	LuaeState L;
-	Luae::openlibs(L);
-
-	LuaeClass::Def cls("Test", {}, {});
-	LuaeClass::create(L, cls);
-
-	Luae::getfield(L, LUA_REGISTRYINDEX, Luae::FieldClasses);
-	CPPUNIT_ASSERT_MESSAGE("Missing __luae_class", Luae::type(L, -1) == LUA_TTABLE);
-
-	Luae::getfield(L, -1, "Test");
-	CPPUNIT_ASSERT_MESSAGE("Missing Test definition", Luae::type(L, -1) == LUA_TTABLE);
-}
-
-void TestLuaeClass::createInheritance()
-{
-	LuaeState L;
-	Luae::openlibs(L);
-
-	LuaeClass::Def ac("A", {}, {});
-	LuaeClass::Def bc("B", {}, {}, ac);
-	LuaeClass::create(L, ac);
-	LuaeClass::create(L, bc);
-
-	Luae::getfield(L, LUA_REGISTRYINDEX, Luae::FieldClasses);
-	CPPUNIT_ASSERT_MESSAGE("Missing __luae_class", Luae::type(L, -1) == LUA_TTABLE);
-
-	Luae::getfield(L, -1, "A");
-	CPPUNIT_ASSERT_MESSAGE("Missing A definition", Luae::type(L, -1) == LUA_TTABLE);
-
-	Luae::getfield(L, -2, "B");
-	CPPUNIT_ASSERT_MESSAGE("Missing B definition", Luae::type(L, -1) == LUA_TTABLE);
-
-	// Check for parent from B -> A
-	Luae::getfield(L, -1, "A");
-	CPPUNIT_ASSERT_MESSAGE("Missing [A] = true", Luae::type(L, -1) == LUA_TBOOLEAN);
-}
-
-void TestLuaeClass::testClass()
-{
-	auto name = [] (lua_State *L) -> int {
-		return Luae::push(L, "object");
-	};
-	auto validate = [] (lua_State *L) -> int {
-		return Luae::push(L, true);
-	};
-
-	LuaeClass::Methods methods {
-		{ "name",	name		},
-		{ "validate",	validate	}
-	};
-
-	LuaeClass::Def object(Luae::TypeInfo<Object>::name, methods, {});
-
-	LuaeState L;
-	Luae::openlibs(L);
-
-	try {
-		LuaeClass::create(L, object);
-		Luae::dofile(L, "class.lua");
-		Luae::getglobal(L, "testObject");
-		Luae::push(L, Object());
-		Luae::pcall(L, 1, 1);
-		CPPUNIT_ASSERT_MESSAGE("o:validate() should return true", Luae::check<bool>(L, -1));
-	} catch (const std::runtime_error &error) {
-		CPPUNIT_ASSERT_MESSAGE("unexpected exception: " + std::string(error.what()), false);
-	}
-}
-
-void TestLuaeClass::testInheritance()
-{
-	auto base = [] (lua_State *L) -> int {
-		Luae::check<Base>(L, 1);
-
-		return Luae::push(L, "base");
-	};
-	auto child = [] (lua_State *L) -> int {
-		Luae::check<Child>(L, 1);
-
-		return Luae::push(L, "child");
-	};
-
-	// Create base class
-	LuaeClass::Methods baseMethods = {
-		{ "base",	base	}
-	};
-	LuaeClass::Def baseDef(Luae::TypeInfo<Base>::name, baseMethods, {});
-
-	// Create child class
-	LuaeClass::Methods childMethods = {
-		{ "child",	child	}
-	};
-	LuaeClass::Def childDef(Luae::TypeInfo<Child>::name, childMethods, {}, baseDef);
-
-	LuaeState L;
-	Luae::openlibs(L);
-	LuaeClass::create(L, baseDef);
-	LuaeClass::create(L, childDef);
-
-	try {
-		Luae::dofile(L, "class.lua");
-		Luae::getglobal(L, "testInheritance");
-		Luae::push(L, Child());
-		Luae::pcall(L, 1, 0);
-	} catch (const std::runtime_error &error) {
-		CPPUNIT_ASSERT_MESSAGE("unexpected exception: " + std::string(error.what()), false);
-	}
-
-	// Do bad inheritance
-	try {
-		Luae::dofile(L, "class.lua");
-		Luae::getglobal(L, "badInheritance");
-		Luae::push(L, Base());
-		Luae::push(L, Child());
-		Luae::pcall(L, 2, 0);
-
-		CPPUNIT_ASSERT_MESSAGE("expected exception", false);
-	} catch (const std::runtime_error &) { }
-}
-
-int main()
-{
-	CppUnit::TextTestRunner runnerText;
-
-	runnerText.addTest(TestLuaeClass::suite());
-
-	return runnerText.run("", false) == 1 ? 0 : 1;
-}
--- a/C++/Tests/Luae/TestLuaeClass.h	Wed Oct 01 14:37:42 2014 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,41 +0,0 @@
-/*
- * TestLuaeClass.h -- test the LuaeClass class
- *
- * Copyright (c) 2013, 2014 David Demelier <markand@malikania.fr>
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-#ifndef _TEST_LUAE_CLASS_H_
-#define _TEST_LUAE_CLASS_H_
-
-#include <cppunit/extensions/HelperMacros.h>
-#include <cppunit/TestFixture.h>
-
-class TestLuaeClass : public CppUnit::TestFixture {
-private:
-	CPPUNIT_TEST_SUITE(TestLuaeClass);
-	CPPUNIT_TEST(create);
-	CPPUNIT_TEST(createInheritance);
-	CPPUNIT_TEST(testClass);
-	CPPUNIT_TEST(testInheritance);
-	CPPUNIT_TEST_SUITE_END();
-
-public:
-	void create();
-	void createInheritance();
-	void testClass();
-	void testInheritance();
-};
-
-#endif // !_TEST_LUAE_CLASS_H_
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/C++/Tests/Luae/main-class.cpp	Wed Oct 01 14:38:25 2014 +0200
@@ -0,0 +1,179 @@
+/*
+ * main-class.cpp -- test the LuaeClass class
+ *
+ * Copyright (c) 2013, 2014 David Demelier <markand@malikania.fr>
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <gtest/gtest.h>
+
+#include <Luae.h>
+#include <LuaeClass.h>
+#include <LuaeState.h>
+
+/* ---------------------------------------------------------
+ * Fake class for TestLuaeClass::create()
+ * --------------------------------------------------------- */
+
+class Object {};
+
+template <>
+struct Luae::TypeInfo<Object> : public Luae::TypeUserdata {
+	static constexpr const char *name = "Object";
+};
+
+/* ---------------------------------------------------------
+ * Fake classes for TestLuaeClass::testInheritance()
+ * --------------------------------------------------------- */
+
+class Base {};
+class Child {};
+
+template <>
+struct Luae::TypeInfo<Base> : public Luae::TypeUserdata {
+	static constexpr const char *name = "Base";
+};
+
+template <>
+struct Luae::TypeInfo<Child> : public Luae::TypeUserdata {
+	static constexpr const char *name = "Child";
+};
+
+TEST(Basic, create)
+{
+	LuaeState L;
+	Luae::openlibs(L);
+
+	LuaeClass::Def cls("Test", {}, {});
+	LuaeClass::create(L, cls);
+
+	Luae::getfield(L, LUA_REGISTRYINDEX, Luae::FieldClasses);
+	ASSERT_TRUE(Luae::type(L, -1) == LUA_TTABLE);
+
+	Luae::getfield(L, -1, "Test");
+	ASSERT_TRUE(Luae::type(L, -1) == LUA_TTABLE);
+}
+
+TEST(Basic, createInheritance)
+{
+	LuaeState L;
+	Luae::openlibs(L);
+
+	LuaeClass::Def ac("A", {}, {});
+	LuaeClass::Def bc("B", {}, {}, ac);
+	LuaeClass::create(L, ac);
+	LuaeClass::create(L, bc);
+
+	Luae::getfield(L, LUA_REGISTRYINDEX, Luae::FieldClasses);
+	ASSERT_TRUE(Luae::type(L, -1) == LUA_TTABLE);
+
+	Luae::getfield(L, -1, "A");
+	ASSERT_TRUE(Luae::type(L, -1) == LUA_TTABLE);
+
+	Luae::getfield(L, -2, "B");
+	ASSERT_TRUE(Luae::type(L, -1) == LUA_TTABLE);
+
+	// Check for parent from B -> A
+	Luae::getfield(L, -1, "A");
+	ASSERT_TRUE(Luae::type(L, -1) == LUA_TBOOLEAN);
+}
+
+TEST(Basic, testClass)
+{
+	auto name = [] (lua_State *L) -> int {
+		return Luae::push(L, "object");
+	};
+	auto validate = [] (lua_State *L) -> int {
+		return Luae::push(L, true);
+	};
+
+	LuaeClass::Methods methods {
+		{ "name",	name		},
+		{ "validate",	validate	}
+	};
+
+	LuaeClass::Def object(Luae::TypeInfo<Object>::name, methods, {});
+
+	LuaeState L;
+	Luae::openlibs(L);
+
+	try {
+		LuaeClass::create(L, object);
+		Luae::dofile(L, "class.lua");
+		Luae::getglobal(L, "testObject");
+		Luae::push(L, Object());
+		Luae::pcall(L, 1, 1);
+		ASSERT_TRUE(Luae::check<bool>(L, -1));
+	} catch (const std::runtime_error &error) {
+		FAIL() << "unexpected exception: "<< error.what();
+	}
+}
+
+TEST(Basic, testInheritance)
+{
+	auto base = [] (lua_State *L) -> int {
+		Luae::check<Base>(L, 1);
+
+		return Luae::push(L, "base");
+	};
+	auto child = [] (lua_State *L) -> int {
+		Luae::check<Child>(L, 1);
+
+		return Luae::push(L, "child");
+	};
+
+	// Create base class
+	LuaeClass::Methods baseMethods = {
+		{ "base",	base	}
+	};
+	LuaeClass::Def baseDef(Luae::TypeInfo<Base>::name, baseMethods, {});
+
+	// Create child class
+	LuaeClass::Methods childMethods = {
+		{ "child",	child	}
+	};
+	LuaeClass::Def childDef(Luae::TypeInfo<Child>::name, childMethods, {}, baseDef);
+
+	LuaeState L;
+	Luae::openlibs(L);
+	LuaeClass::create(L, baseDef);
+	LuaeClass::create(L, childDef);
+
+	try {
+		Luae::dofile(L, "class.lua");
+		Luae::getglobal(L, "testInheritance");
+		Luae::push(L, Child());
+		Luae::pcall(L, 1, 0);
+	} catch (const std::runtime_error &error) {
+		FAIL() << "unexpected exception: " << error.what();
+	}
+
+	// Do bad inheritance
+	try {
+		Luae::dofile(L, "class.lua");
+		Luae::getglobal(L, "badInheritance");
+		Luae::push(L, Base());
+		Luae::push(L, Child());
+		Luae::pcall(L, 2, 0);
+
+		FAIL() << "expected exception";
+	} catch (const std::runtime_error &) { }
+}
+
+int main(int argc, char **argv)
+{
+	testing::InitGoogleTest(&argc, argv);
+
+	return RUN_ALL_TESTS();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/C++/Tests/Luae/main.cpp	Wed Oct 01 14:38:25 2014 +0200
@@ -0,0 +1,488 @@
+/*
+ * main.cpp -- test the Luae class
+ *
+ * Copyright (c) 2013, 2014 David Demelier <markand@malikania.fr>
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <gtest/gtest.h>
+
+#include <Luae.h>
+#include <LuaeState.h>
+
+/* --------------------------------------------------------
+ * Custom type Point
+ * -------------------------------------------------------- */
+
+struct Point {
+	int x;
+	int y;
+};
+
+template <>
+struct Luae::TypeInfo<Point> : Luae::TypeCustom {
+	static void push(lua_State *L, const Point &point)
+	{
+		lua_createtable(L, 0, 0);
+		lua_pushinteger(L, point.x);
+		lua_setfield(L, -2, "x");
+		lua_pushinteger(L, point.y);
+		lua_setfield(L, -2, "y");
+	}
+
+	static Point get(lua_State *L, int index)
+	{
+		Point p{0, 0};
+
+		if (lua_type(L, index) == LUA_TTABLE) {
+			lua_getfield(L, index, "x");
+			p.x = luaL_optint(L, -1, 0);
+			lua_pop(L, 1);
+			lua_getfield(L, index, "y");
+			p.y = luaL_optint(L, -1, 0);
+			lua_pop(L, 1);
+		}
+
+		return p;
+	}
+
+	static Point check(lua_State *L, int index)
+	{
+		luaL_checktype(L, index, LUA_TTABLE);
+
+		return get(L, index);
+	}
+};
+
+/* --------------------------------------------------------
+ * Userdata type Object
+ * -------------------------------------------------------- */
+
+struct Object {
+	std::string hello()
+	{
+		return "hello";
+	}
+};
+
+template <>
+struct Luae::TypeInfo<Object> : Luae::TypeUserdata {
+	static constexpr const char *name = "Object";
+};
+
+int l_hello(lua_State *L)
+{
+	return Luae::push(L, Luae::check<Object>(L, 1)->hello());
+}
+
+const Luae::Reg methods {
+	{ "hello",	l_hello		}
+};
+
+/* --------------------------------------------------------
+ * Userdata as shared_ptr Widget
+ * -------------------------------------------------------- */
+
+class Widget {
+private:
+	int		m_width;
+	int		m_height;
+	std::string	m_name;
+
+public:
+	Widget(int width, int height, const std::string &name)
+		: m_width(width)
+		, m_height(height)
+		, m_name(name)
+	{
+	}
+
+	int width() const
+	{
+		return m_width;
+	}
+
+	int height() const
+	{
+		return m_height;
+	}
+
+	const std::string &name() const
+	{
+		return m_name;
+	}
+};
+
+using WidgetPtr	= std::shared_ptr<Widget>;
+
+template <>
+struct Luae::TypeInfo<Widget> : Luae::TypeUserdata {
+	static constexpr const char *name = "Widget";
+};
+
+int l_width(lua_State *L)
+{
+	return Luae::push(L, Luae::check<WidgetPtr>(L, 1)->width());
+}
+
+int l_height(lua_State *L)
+{
+	return Luae::push(L, Luae::check<WidgetPtr>(L, 1)->height());
+}
+
+int l_name(lua_State *L)
+{
+	return Luae::push(L, Luae::check<WidgetPtr>(L, 1)->name());
+}
+
+const Luae::Reg widgetMethods {
+	{ "width",		l_width		},
+	{ "height",		l_height	},
+	{ "name",		l_name		}
+};
+
+/* --------------------------------------------------------
+ * Push function tests
+ * -------------------------------------------------------- */
+
+TEST(Push, point)
+{
+	LuaeState L;
+	Luae::openlibs(L);
+
+	try {
+		Luae::dofile(L, "push.lua");
+		Luae::getglobal(L, "pushPoint");
+		Luae::push(L, Point{10, 20});
+		Luae::pcall(L, 1, 0);
+	} catch (const std::runtime_error &error) {
+		FAIL() << "unexpected exception: " << error.what();
+	}
+}
+
+TEST(Push, object)
+{
+	LuaeState L;
+	Luae::openlibs(L);
+
+	// Object metatable
+	Luae::newmetatable(L, "Object");
+	Luae::newlib(L, methods);
+	Luae::setfield(L, -2, "__index");
+	Luae::pop(L);
+
+	try {
+		Luae::dofile(L, "push.lua");
+		Luae::getglobal(L, "pushObject");
+		Luae::push(L, Object());
+		Luae::pcall(L, 1, 0);
+	} catch (const std::runtime_error &error) {
+		FAIL() << "unexpected exception: " << error.what();
+	}
+}
+
+TEST(Push, shared)
+{
+	LuaeState L;
+	Luae::openlibs(L);
+
+	// Widget metatable
+	Luae::newmetatable(L, "Widget");
+	Luae::newlib(L, widgetMethods);
+	Luae::setfield(L, -2, "__index");
+	Luae::pop(L);
+
+	try {
+		Luae::dofile(L, "push.lua");
+		Luae::getglobal(L, "pushShared");
+		Luae::push(L, std::make_shared<Widget>(100, 200, "Button"));
+		Luae::pcall(L, 1, 0);
+	} catch (const std::runtime_error &error) {
+		FAIL() << "unexpected exception: " << error.what();
+	}
+}
+
+TEST(Push, sharedTwice)
+{
+	LuaeState L;
+	Luae::openlibs(L);
+
+	// Widget metatable
+	Luae::newmetatable(L, "Widget");
+	Luae::newlib(L, widgetMethods);
+	Luae::setfield(L, -2, "__index");
+	Luae::pop(L);
+
+	try {
+		auto widget = std::make_shared<Widget>(640, 480, "Screen");
+
+		Luae::dofile(L, "push.lua");
+		Luae::getglobal(L, "pushSharedTwice");
+		Luae::push(L, widget);
+		Luae::push(L, widget);
+		Luae::pcall(L, 2, 0);
+	} catch (const std::runtime_error &error) {
+		FAIL() << "unexpected exception: " << error.what();
+	}
+}
+
+/* --------------------------------------------------------
+ * Other functions
+ * -------------------------------------------------------- */
+
+TEST(Basic, preload)
+{
+	LuaeState L;
+	Luae::openlibs(L);
+
+	Luae::preload(L, "luae", [] (lua_State *L) -> int {
+		lua_createtable(L, 0, 0);
+		lua_pushstring(L, "1.0");
+		lua_setfield(L, -2, "version");
+		lua_pushstring(L, "Luae");
+		lua_setfield(L, -2, "name");
+
+		return 1;
+	});
+
+	try {
+		Luae::dofile(L, "loading.lua");
+		Luae::getglobal(L, "test");
+	} catch (const std::runtime_error &error) {
+		FAIL() << "unexpected exception: " << error.what();
+	}
+}
+
+TEST(Basic, require)
+{
+	LuaeState L;
+	Luae::openlibs(L);
+
+	Luae::require(L, "luae", [] (lua_State *L) -> int {
+		lua_createtable(L, 0, 0);
+		lua_pushstring(L, "1.0");
+		lua_setfield(L, -2, "version");
+		lua_pushstring(L, "Luae");
+		lua_setfield(L, -2, "name");
+
+		return 1;
+	});
+
+	try {
+		Luae::dofile(L, "loading.lua");
+		Luae::getglobal(L, "test");
+	} catch (const std::runtime_error &error) {
+		FAIL() << "unexpected exception: "  << error.what();
+	}
+}
+
+/* --------------------------------------------------------
+ * Standard types push / get / check
+ * -------------------------------------------------------- */
+
+TEST(Standard, testbool)
+{
+	LuaeState L;
+	Luae::openlibs(L);
+
+	try {
+		Luae::dofile(L, "standard.lua");
+		Luae::getglobal(L, "testbool");
+		Luae::push(L, true);
+		Luae::pcall(L, 1, 1);
+		ASSERT_FALSE(Luae::check<bool>(L, 1));
+	} catch (const std::runtime_error &error) {
+		FAIL() << "unexpected exception: " << error.what();
+	}
+}
+
+TEST(Standard, testdouble)
+{
+	LuaeState L;
+	Luae::openlibs(L);
+
+	try {
+		Luae::dofile(L, "standard.lua");
+		Luae::getglobal(L, "testdouble");
+		Luae::push(L, 10.0);
+		Luae::pcall(L, 1, 1);
+		ASSERT_EQ(-10.0, Luae::check<double>(L, 1));
+	} catch (const std::runtime_error &error) {
+		FAIL() << "unexpected exception: " << error.what();
+	}
+}
+
+TEST(Standard, testint)
+{
+	LuaeState L;
+	Luae::openlibs(L);
+
+	try {
+		Luae::dofile(L, "standard.lua");
+		Luae::getglobal(L, "testint");
+		Luae::push(L, 123);
+		Luae::pcall(L, 1, 1);
+		ASSERT_EQ(-123, Luae::check<int>(L, 1));
+	} catch (const std::runtime_error &error) {
+		FAIL() << "unexpected exception: " << error.what();
+	}
+}
+
+TEST(Standard, testlong)
+{
+	LuaeState L;
+	Luae::openlibs(L);
+
+	try {
+		Luae::dofile(L, "standard.lua");
+		Luae::getglobal(L, "testlong");
+		Luae::push(L, 9999L);
+		Luae::pcall(L, 1, 1);
+		ASSERT_EQ(-9999L, Luae::check<long>(L, 1));
+	} catch (const std::runtime_error &error) {
+		FAIL() << "unexpected exception: " << error.what();
+	}
+}
+
+TEST(Standard, testnil)
+{
+	LuaeState L;
+	Luae::openlibs(L);
+
+	try {
+		Luae::dofile(L, "standard.lua");
+		Luae::getglobal(L, "testnil");
+		Luae::push(L, nullptr);
+		Luae::pcall(L, 1, 1);
+		ASSERT_EQ(LUA_TNIL, Luae::type(L, -1));
+	} catch (const std::runtime_error &error) {
+		FAIL() << "unexpected exception: " << error.what();
+	}
+}
+
+TEST(Standard, teststring)
+{
+	LuaeState L;
+	Luae::openlibs(L);
+
+	try {
+		Luae::dofile(L, "standard.lua");
+		Luae::getglobal(L, "teststring");
+		Luae::push(L, "Hello");
+		Luae::pcall(L, 1, 1);
+		ASSERT_EQ("olleH", Luae::check<std::string>(L, 1));
+	} catch (const std::runtime_error &error) {
+		FAIL() << "unexpected exception: " << error.what();
+	}
+}
+
+TEST(Standard, testustring)
+{
+	LuaeState L;
+	Luae::openlibs(L);
+
+	try {
+		std::u32string arg{'H', 'e', 'l', 'l', 'o'};
+		std::u32string expected{'o', 'l', 'l', 'e', 'H'};
+
+		Luae::dofile(L, "standard.lua");
+		Luae::getglobal(L, "testustring");
+		Luae::push(L, arg);
+		Luae::pcall(L, 1, 1);
+		ASSERT_EQ(expected, Luae::check<std::u32string>(L, 1));
+	} catch (const std::runtime_error &error) {
+		FAIL() << "unexpected exception: " << error.what();
+	}
+}
+
+TEST(Standard, optionalbool)
+{
+	LuaeState L;
+	Luae::openlibs(L);
+
+	Luae::push(L, nullptr);
+	ASSERT_FALSE(Luae::optional<bool>(L, -1, false));
+
+	Luae::push(L, true);
+	ASSERT_TRUE(Luae::optional<bool>(L, -1, false));
+}
+
+TEST(Standard, optionalint)
+{
+	LuaeState L;
+	Luae::openlibs(L);
+
+	Luae::push(L, nullptr);
+	ASSERT_EQ(123, Luae::optional<int>(L, -1, 123));
+
+	Luae::push(L, 456);
+	ASSERT_EQ(456, Luae::optional<int>(L, -1, 999));
+}
+
+TEST(Standard, optionallong)
+{
+	LuaeState L;
+	Luae::openlibs(L);
+
+	Luae::push(L, nullptr);
+	ASSERT_EQ(123456789, Luae::optional<long>(L, -1, 123456789));
+
+	Luae::push(L, 789);
+	ASSERT_EQ(789, Luae::optional<long>(L, -1, 888));
+}
+
+TEST(Standard, optionaldouble)
+{
+	LuaeState L;
+	Luae::openlibs(L);
+
+	Luae::push(L, nullptr);
+	ASSERT_EQ(123.321, Luae::optional<double>(L, -1, 123.321));
+
+	Luae::push(L, 99.44);
+	ASSERT_EQ(99.44, Luae::optional<double>(L, -1, 321.321));
+}
+
+TEST(Standard, optionalstring)
+{
+	LuaeState L;
+	Luae::openlibs(L);
+
+	Luae::push(L, nullptr);
+	ASSERT_EQ("abc", Luae::optional<std::string>(L, -1, "abc"));
+
+	Luae::push(L, "xyz");
+	ASSERT_EQ("xyz", Luae::optional<std::string>(L, -1, "qwerty"));
+}
+
+TEST(Standard, optionalustring)
+{
+	LuaeState L;
+	Luae::openlibs(L);
+
+	std::u32string expected { 'a', 'b', 'c' };
+	Luae::push(L, nullptr);
+	ASSERT_EQ(expected, Luae::optional<std::u32string>(L, -1, expected));
+
+	std::u32string notthatone { 'x', 'y' };
+	Luae::push(L, expected);
+	ASSERT_EQ(expected, Luae::optional<std::u32string>(L, -1, notthatone));
+}
+
+int main(int argc, char **argv)
+{
+	testing::InitGoogleTest(&argc, argv);
+
+	return RUN_ALL_TESTS();
+}
--- a/C++/Tests/Pack/CMakeLists.txt	Wed Oct 01 14:37:42 2014 +0200
+++ b/C++/Tests/Pack/CMakeLists.txt	Wed Oct 01 14:38:25 2014 +0200
@@ -20,8 +20,7 @@
 	SOURCES
 	${code_SOURCE_DIR}/C++/Pack.cpp
 	${code_SOURCE_DIR}/C++/Pack.h
-	TestPack.cpp
-	TestPack.h
+	main.cpp
 )
 
 define_test(pack "${SOURCES}")
--- a/C++/Tests/Pack/TestPack.cpp	Wed Oct 01 14:37:42 2014 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,68 +0,0 @@
-/*
- * TestPack.cpp -- test the pack serializer
- *
- * Copyright (c) 2013, 2014 David Demelier <markand@malikania.fr>
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-#include <cppunit/TextTestRunner.h>
-
-#include <Pack.h>
-
-#include "TestPack.h"
-
-void TestPack::simpleLittleEndian()
-{
-	uint8_t u8(1), r8;
-	uint16_t u16(2), r16;
-	uint32_t u32(3), r32;
-	uint64_t u64(4), r64;
-
-	try {
-		Pack::write("simple-little.bin", Pack::Little, u8, u16, u32, u64);
-		Pack::read("simple-little.bin", Pack::Little, r8, r16, r32, r64);
-
-		CPPUNIT_ASSERT_EQUAL(r8, u8);
-		CPPUNIT_ASSERT_EQUAL(r16, u16);
-		CPPUNIT_ASSERT_EQUAL(r32, u32);
-		CPPUNIT_ASSERT_EQUAL(r64, u64);
-	} catch (const std::runtime_error &) { }
-}
-
-void TestPack::simpleBigEndian()
-{
-	uint8_t u8(1), r8;
-	uint16_t u16(2), r16;
-	uint32_t u32(3), r32;
-	uint64_t u64(4), r64;
-
-	try {
-		Pack::write("simple-big.bin", Pack::Big, u8, u16, u32, u64);
-		Pack::read("simple-big.bin", Pack::Big, r8, r16, r32, r64);
-
-		CPPUNIT_ASSERT_EQUAL(r8, u8);
-		CPPUNIT_ASSERT_EQUAL(r16, u16);
-		CPPUNIT_ASSERT_EQUAL(r32, u32);
-		CPPUNIT_ASSERT_EQUAL(r64, u64);
-	} catch (const std::runtime_error &) { }
-}
-
-int main()
-{
-	CppUnit::TextTestRunner runnerText;
-
-	runnerText.addTest(TestPack::suite());
-
-	return runnerText.run("", false) == 1 ? 0 : 1;
-}
\ No newline at end of file
--- a/C++/Tests/Pack/TestPack.h	Wed Oct 01 14:37:42 2014 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,37 +0,0 @@
-/*
- * TestPack.h -- test the pack serializer
- *
- * Copyright (c) 2013, 2014 David Demelier <markand@malikania.fr>
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-#ifndef _TEST_PACK_H_
-#define _TEST_PACK_H_
-
-#include <cppunit/extensions/HelperMacros.h>
-#include <cppunit/TestFixture.h>
-
-class TestPack : public CppUnit::TestFixture {
-private:
-	CPPUNIT_TEST_SUITE(TestPack);
-	CPPUNIT_TEST(simpleLittleEndian);
-	CPPUNIT_TEST(simpleBigEndian);
-	CPPUNIT_TEST_SUITE_END();
-
-public:
-	void simpleLittleEndian();
-	void simpleBigEndian();
-};
-
-#endif // !_TEST_PACK_H_
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/C++/Tests/Pack/main.cpp	Wed Oct 01 14:38:25 2014 +0200
@@ -0,0 +1,68 @@
+/*
+ * TestPack.cpp -- test the pack serializer
+ *
+ * Copyright (c) 2013, 2014 David Demelier <markand@malikania.fr>
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <gtest/gtest.h>
+
+#include <Pack.h>
+
+TEST(Simple, simpleLittleEndian)
+{
+	uint8_t u8(1), r8;
+	uint16_t u16(2), r16;
+	uint32_t u32(3), r32;
+	uint64_t u64(4), r64;
+
+	try {
+		Pack::write("simple-little.bin", Pack::Little, u8, u16, u32, u64);
+		Pack::read("simple-little.bin", Pack::Little, r8, r16, r32, r64);
+
+		ASSERT_EQ(u8, r8);
+		ASSERT_EQ(u16, r16);
+		ASSERT_EQ(u32, r32);
+		ASSERT_EQ(u64, r64);
+	} catch (const std::runtime_error &error) {
+		FAIL() << error.what();
+	}
+}
+
+TEST(Simple, simpleBigEndian)
+{
+	uint8_t u8(1), r8;
+	uint16_t u16(2), r16;
+	uint32_t u32(3), r32;
+	uint64_t u64(4), r64;
+
+	try {
+		Pack::write("simple-big.bin", Pack::Big, u8, u16, u32, u64);
+		Pack::read("simple-big.bin", Pack::Big, r8, r16, r32, r64);
+
+		ASSERT_EQ(u8, r8);
+		ASSERT_EQ(u16, r16);
+		ASSERT_EQ(u32, r32);
+		ASSERT_EQ(u64, r64);
+	} catch (const std::runtime_error &error) {
+		FAIL() << error.what();
+	}
+}
+
+int main(int argc, char **argv)
+{
+	testing::InitGoogleTest(&argc, argv);
+
+	return RUN_ALL_TESTS();
+}
\ No newline at end of file
--- a/C++/Tests/Parser/CMakeLists.txt	Wed Oct 01 14:37:42 2014 +0200
+++ b/C++/Tests/Parser/CMakeLists.txt	Wed Oct 01 14:38:25 2014 +0200
@@ -20,8 +20,7 @@
 	SOURCES
 	${code_SOURCE_DIR}/C++/Parser.cpp
 	${code_SOURCE_DIR}/C++/Parser.h
-	TestParser.cpp
-	TestParser.h
+	main.cpp
 	configs/simple.conf
 	configs/multi.conf
 )
--- a/C++/Tests/Parser/TestParser.cpp	Wed Oct 01 14:37:42 2014 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,102 +0,0 @@
-/*
- * TestParser.cpp -- test the config file parser
- *
- * Copyright (c) 2013, 2014 David Demelier <markand@malikania.fr>
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-#include <iostream>
-
-#include <cppunit/TextTestRunner.h>
-
-#include <Parser.h>
-
-#include "TestParser.h"
-
-void TestParser::simple()
-{
-	try {
-		Parser parser("simple.conf");
-
-		const auto &s = parser.getSection("general");
-		CPPUNIT_ASSERT_EQUAL(std::string("general"), s.getName());
-
-		const auto &o1 = s.getOption<std::string>("option1");
-		CPPUNIT_ASSERT_EQUAL(std::string("1"), o1);
-
-		const auto &o2 = s.getOption<std::string>("option2");
-		CPPUNIT_ASSERT_EQUAL(std::string("2"), o2);
-
-		const auto &o3 = s.getOption<std::string>("option3");
-		CPPUNIT_ASSERT_EQUAL(std::string("3"), o3);
-	} catch (const std::out_of_range &error) {
-		CPPUNIT_ASSERT_MESSAGE("unexpected exception", false);
-	} catch (const std::runtime_error &error) {
-		std::cout << "skipping because: " << error.what() << std::endl;
-	}
-}
-
-void TestParser::multi()
-{
-	try {
-		Parser parser("multi.conf");
-		int i(0);
-
-		parser.findSections("entity", [&] (const Section &s) {
-			if (i++ == 0) {
-				CPPUNIT_ASSERT_EQUAL(std::string("Player"), s.getOption<std::string>("name"));
-				CPPUNIT_ASSERT_EQUAL(std::string("1.0"), s.getOption<std::string>("version"));
-			} else {
-				CPPUNIT_ASSERT_EQUAL(std::string("Subwinner"), s.getOption<std::string>("name"));
-				CPPUNIT_ASSERT_EQUAL(std::string("2.0"), s.getOption<std::string>("version"));
-			}
-		});
-
-		CPPUNIT_ASSERT_EQUAL(2, i);
-	} catch (const std::out_of_range &error) {
-		CPPUNIT_ASSERT_MESSAGE("unexpected exception", false);
-	} catch (const std::runtime_error &error) {
-		std::cout << "skipping because: " << error.what() << std::endl;
-	}
-}
-
-void TestParser::multiNoredef()
-{
-	try {
-		Parser parser("multi.conf", Parser::DisableRedefinition);
-		int i(0);
-
-		parser.findSections("entity", [&] (const Section &s) {
-			if (i++ == 0) {
-				CPPUNIT_ASSERT_EQUAL(std::string("Player"), s.getOption<std::string>("name"));
-				CPPUNIT_ASSERT_EQUAL(std::string("1.0"), s.getOption<std::string>("version"));
-			}
-		});
-
-		CPPUNIT_ASSERT_EQUAL(1, i);
-	} catch (const std::out_of_range &error) {
-		CPPUNIT_ASSERT_MESSAGE("unexpected exception", false);
-	} catch (const std::runtime_error &error) {
-		std::cout << "skipping because: " << error.what() << std::endl;
-	}
-}
-
-int main()
-{
-	CppUnit::TextTestRunner runnerText;
-
-	runnerText.addTest(TestParser::suite());
-
-	return runnerText.run("", false) == 1 ? 0 : 1;
-}
\ No newline at end of file
--- a/C++/Tests/Parser/TestParser.h	Wed Oct 01 14:37:42 2014 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,39 +0,0 @@
-/*
- * TestParser.h -- test the config file parser
- *
- * Copyright (c) 2013, 2014 David Demelier <markand@malikania.fr>
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-#ifndef _TEST_PARSER_H_
-#define _TEST_PARSER_H_
-
-#include <cppunit/extensions/HelperMacros.h>
-#include <cppunit/TestFixture.h>
-
-class TestParser : public CppUnit::TestFixture {
-private:
-	CPPUNIT_TEST_SUITE(TestParser);
-	CPPUNIT_TEST(simple);
-	CPPUNIT_TEST(multi);
-	CPPUNIT_TEST(multiNoredef);
-	CPPUNIT_TEST_SUITE_END();
-
-public:
-	void simple();
-	void multi();
-	void multiNoredef();
-};
-
-#endif // !_TEST_PARSER_H_
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/C++/Tests/Parser/main.cpp	Wed Oct 01 14:38:25 2014 +0200
@@ -0,0 +1,98 @@
+/*
+ * TestParser.cpp -- test the config file parser
+ *
+ * Copyright (c) 2013, 2014 David Demelier <markand@malikania.fr>
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <iostream>
+
+#include <gtest/gtest.h>
+
+#include <Parser.h>
+
+TEST(Basic, simple)
+{
+	try {
+		Parser parser("simple.conf");
+
+		const auto &s = parser.getSection("general");
+		ASSERT_EQ("general", s.getName());
+
+		const auto &o1 = s.getOption<std::string>("option1");
+		ASSERT_EQ("1", o1);
+
+		const auto &o2 = s.getOption<std::string>("option2");
+		ASSERT_EQ("2", o2);
+
+		const auto &o3 = s.getOption<std::string>("option3");
+		ASSERT_EQ("3", o3);
+	} catch (const std::out_of_range &error) {
+		FAIL();
+	} catch (const std::runtime_error &error) {
+		FAIL() << error.what();
+	}
+}
+
+TEST(Basic, multi)
+{
+	try {
+		Parser parser("multi.conf");
+		int i(0);
+
+		parser.findSections("entity", [&] (const Section &s) {
+			if (i++ == 0) {
+				ASSERT_EQ("Player", s.getOption<std::string>("name"));
+				ASSERT_EQ("1.0", s.getOption<std::string>("version"));
+			} else {
+				ASSERT_EQ("Subwinner", s.getOption<std::string>("name"));
+				ASSERT_EQ("2.0", s.getOption<std::string>("version"));
+			}
+		});
+
+		ASSERT_EQ(2, i);
+	} catch (const std::out_of_range &error) {
+		FAIL();
+	} catch (const std::runtime_error &error) {
+		FAIL() << error.what();
+	}
+}
+
+TEST(Basic, multiNoredef)
+{
+	try {
+		Parser parser("multi.conf", Parser::DisableRedefinition);
+		int i(0);
+
+		parser.findSections("entity", [&] (const Section &s) {
+			if (i++ == 0) {
+				ASSERT_EQ("Player", s.getOption<std::string>("name"));
+				ASSERT_EQ("1.0", s.getOption<std::string>("version"));
+			}
+		});
+
+		ASSERT_EQ(1, i);
+	} catch (const std::out_of_range &error) {
+		FAIL();
+	} catch (const std::runtime_error &error) {
+		FAIL() << error.what();
+	}
+}
+
+int main(int argc, char **argv)
+{
+	testing::InitGoogleTest(&argc, argv);
+
+	return RUN_ALL_TESTS();
+}
\ No newline at end of file
--- a/CMakeLists.txt	Wed Oct 01 14:37:42 2014 +0200
+++ b/CMakeLists.txt	Wed Oct 01 14:38:25 2014 +0200
@@ -31,9 +31,6 @@
 	${code_SOURCE_DIR}/C++
 )
 
-# Cppunit is the old unit tester which being replaced slowly by googletest
-find_package(Cppunit REQUIRED)
-
 # GoogleTest library
 add_subdirectory(extern)
 
@@ -44,15 +41,7 @@
 		${sources}
 	)
 
-	# Get rid of cppunit warning shit
-	if (NOT WIN32)
-		target_compile_options(${name} PRIVATE "-Wno-unused-parameter")
-	endif()
-
-	# Also link to gtest until cppunit is removed
-
-	target_include_directories(${name} PRIVATE ${CPPUNIT_INCLUDE_DIR})
-	target_link_libraries(${name} ${CPPUNIT_LIBRARY} gtest)
+	target_link_libraries(${name} gtest)
 	add_test(${name}-test ${name})
 endfunction()
 
@@ -69,7 +58,10 @@
 option(WITH_SOCKET "Enable sockets tests" On)
 option(WITH_UTF8 "Enable Utf8 functions tests" On)
 option(WITH_XMLPARSER "Enable XML tests" On)
-option(WITH_XDG "Enable XDG standard directories tests" On)
+
+if (UNIX)
+	option(WITH_XDG "Enable XDG standard directories tests" On)
+endif ()
 
 if (WITH_BASE64)
 	add_subdirectory(C++/Tests/Base64)
@@ -103,6 +95,6 @@
 	add_subdirectory(C++/Tests/Parser)
 endif ()
 
-if (WITH_XDG)
+if (WITH_XDG AND UNIX)
 	add_subdirectory(C++/Tests/Xdg)
 endif ()