changeset 80:a162f380f02e

CMake: create examples, closes #615
author David Demelier <markand@malikania.fr>
date Sun, 22 Jan 2017 09:59:14 +0100
parents 8b41e9a2e095
children 301599387b40
files CMakeLists.txt cmake/function/MalikaniaDefineExample.cmake examples/CMakeLists.txt examples/animation/CMakeLists.txt examples/animation/main.cpp examples/font/CMakeLists.txt examples/font/main.cpp examples/image/CMakeLists.txt examples/image/main.cpp examples/image/resources/images/100x10.png examples/image/resources/images/10x100.png examples/image/resources/images/16x16.png examples/image/resources/images/smiley.xcf examples/js-animation/CMakeLists.txt examples/js-animation/main.cpp examples/js-font/CMakeLists.txt examples/js-font/main.cpp examples/js-image/CMakeLists.txt examples/js-image/main.cpp examples/js-sprite/CMakeLists.txt examples/js-sprite/main.cpp examples/js-window/CMakeLists.txt examples/js-window/main.cpp examples/sprite/CMakeLists.txt examples/sprite/main.cpp examples/sprite/resources/images/margins.xcf examples/sprite/resources/images/mokodemo.png examples/sprite/resources/sprites/image-not-found.json examples/sprite/resources/sprites/no-property-cell.json examples/sprite/resources/sprites/no-property-image.json examples/sprite/resources/sprites/not-object.json examples/sprite/resources/sprites/property-cell-not-array.json examples/sprite/resources/sprites/property-cell-not-array2.json examples/sprite/resources/sprites/property-image-not-string.json examples/sprite/resources/sprites/simple.json
diffstat 35 files changed, 354 insertions(+), 774 deletions(-) [+]
line wrap: on
line diff
--- a/CMakeLists.txt	Sat Jan 21 14:13:52 2017 +0100
+++ b/CMakeLists.txt	Sun Jan 22 09:59:14 2017 +0100
@@ -32,6 +32,7 @@
 
 include(cmake/function/MalikaniaBuildAssets.cmake)
 include(cmake/function/MalikaniaDefineLibrary.cmake)
+include(cmake/function/MalikaniaDefineExample.cmake)
 include(cmake/function/MalikaniaDefineExecutable.cmake)
 include(cmake/function/MalikaniaDefineTest.cmake)
 include(cmake/function/MalikaniaSetg.cmake)
@@ -52,6 +53,7 @@
 find_package(ZIP REQUIRED)
 
 add_subdirectory(tools)
+add_subdirectory(examples)
 add_subdirectory(extern)
 add_subdirectory(database)
 add_subdirectory(docs)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/cmake/function/MalikaniaDefineExample.cmake	Sun Jan 22 09:59:14 2017 +0100
@@ -0,0 +1,39 @@
+#
+# MalikaniaDefineExample.cmake -- CMake build system for malikania
+#
+# Copyright (c) 2013-2017 Malikania Authors
+#
+# 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(CMakeParseArguments)
+
+include(${CMAKE_CURRENT_LIST_DIR}/MalikaniaVeraCheck.cmake)
+
+function(malikania_define_example)
+    set(singleArgs TARGET)
+    set(multiArgs FLAGS LIBRARIES SOURCES)
+
+    cmake_parse_arguments(EXP "" "${singleArgs}" "${multiArgs}" ${ARGN})
+
+    if (NOT EXP_TARGET)
+        message(FATAL_ERROR "Missing TARGET parameter")
+    elseif (NOT EXP_SOURCES)
+        message(FATAL_ERROR "Missing SOURCES parameter")
+    endif ()
+
+    list(APPEND EXP_FLAGS SOURCE_DIRECTORY=\"${CMAKE_CURRENT_SOURCE_DIR}/resources\")
+    add_executable(example-${EXP_TARGET} ${EXP_SOURCES})
+    target_link_libraries(example-${EXP_TARGET} ${EXP_LIBRARIES})
+    target_compile_definitions(example-${EXP_TARGET} PRIVATE ${EXP_FLAGS})
+endfunction()
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/examples/CMakeLists.txt	Sun Jan 22 09:59:14 2017 +0100
@@ -0,0 +1,27 @@
+#
+# CMakeLists.txt -- CMake build system for malikania
+#
+# Copyright (c) 2013-2017 Malikania Authors
+#
+# 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.
+#
+
+add_subdirectory(animation)
+add_subdirectory(font)
+add_subdirectory(image)
+add_subdirectory(js-animation)
+add_subdirectory(js-font)
+add_subdirectory(js-image)
+add_subdirectory(js-sprite)
+add_subdirectory(js-window)
+add_subdirectory(sprite)
--- a/examples/animation/CMakeLists.txt	Sat Jan 21 14:13:52 2017 +0100
+++ b/examples/animation/CMakeLists.txt	Sun Jan 22 09:59:14 2017 +0100
@@ -1,7 +1,7 @@
 #
 # CMakeLists.txt -- CMake build system for malikania
 #
-# Copyright (c) 2013-2016 Malikania Authors
+# Copyright (c) 2013-2017 Malikania Authors
 #
 # Permission to use, copy, modify, and/or distribute this software for any
 # purpose with or without fee is hereby granted, provided that the above
@@ -16,12 +16,8 @@
 # OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 #
 
-malikania_create_test(
-    NAME animation
+malikania_define_example(
+    TARGET animation
     LIBRARIES libmlk-client
     SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/main.cpp
-    RESOURCES
-        resources/animations/margins.json
-        resources/images/margins.png
-        resources/sprites/margins.json
 )
--- a/examples/animation/main.cpp	Sat Jan 21 14:13:52 2017 +0100
+++ b/examples/animation/main.cpp	Sun Jan 22 09:59:14 2017 +0100
@@ -1,7 +1,7 @@
 /*
  * main.cpp -- test animation
  *
- * Copyright (c) 2013-2016 Malikania Authors
+ * Copyright (c) 2013-2017 Malikania Authors
  *
  * Permission to use, copy, modify, and/or distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
@@ -20,65 +20,21 @@
 #include <thread>
 #include <exception>
 
-#define BOOST_TEST_MODULE "Animation"
-#include <boost/test/unit_test.hpp>
-
 #include <malikania/animation.hpp>
 #include <malikania/animator.hpp>
 #include <malikania/client_resources_loader.hpp>
 #include <malikania/resources_locator.hpp>
 #include <malikania/window.hpp>
 
-namespace {
-
-mlk::window win(400, 400);
-
-} // !namespace
-
-class test_animation {
-protected:
-    mlk::directory_resources_locator m_locator;
-    mlk::client_resources_loader m_loader;
-
-public:
-    test_animation()
-        : m_locator(SOURCE_DIRECTORY "/resources")
-        , m_loader(m_locator)
-    {
-    }
-};
-
-BOOST_FIXTURE_TEST_SUITE(test_animation_suite, test_animation)
-
-BOOST_AUTO_TEST_CASE(standard)
-{
-    try {
-        auto animation = m_loader.load_animation("animations/margins.json");
-
-        BOOST_REQUIRE_EQUAL(12U, animation.frames().size());
-        BOOST_REQUIRE_EQUAL(500U, animation[0].delay());
-        BOOST_REQUIRE_EQUAL(501U, animation[1].delay());
-        BOOST_REQUIRE_EQUAL(502U, animation[2].delay());
-        BOOST_REQUIRE_EQUAL(503U, animation[3].delay());
-        BOOST_REQUIRE_EQUAL(504U, animation[4].delay());
-        BOOST_REQUIRE_EQUAL(505U, animation[5].delay());
-        BOOST_REQUIRE_EQUAL(506U, animation[6].delay());
-        BOOST_REQUIRE_EQUAL(507U, animation[7].delay());
-        BOOST_REQUIRE_EQUAL(508U, animation[8].delay());
-        BOOST_REQUIRE_EQUAL(509U, animation[9].delay());
-        BOOST_REQUIRE_EQUAL(510U, animation[10].delay());
-        BOOST_REQUIRE_EQUAL(511U, animation[11].delay());
-    } catch (const std::exception &ex) {
-        BOOST_FAIL(ex.what());
-    }
-}
-
-BOOST_AUTO_TEST_CASE(draw)
+int main()
 {
     boost::timer::cpu_timer timer;
 
     try {
-        mlk::animation animation = m_loader.load_animation("animations/margins.json");
+        mlk::window win(400, 400);
+        mlk::directory_resources_locator locator(SOURCE_DIRECTORY);
+        mlk::client_resources_loader loader(locator);
+        mlk::animation animation = loader.load_animation("animations/margins.json");
         mlk::animator animator(animation);
 
         auto x = (400 / 2) - (animation.sprite().cell().width() / 2);
@@ -90,9 +46,8 @@
             animator.update();
             win.present();
         }
-    } catch (const std::exception &ex) {
-        BOOST_FAIL(ex.what());
+    } catch (const std::exception& ex) {
+        std::cerr << ex.what() << std::endl;
+        return 1;
     }
 }
-
-BOOST_AUTO_TEST_SUITE_END()
--- a/examples/font/CMakeLists.txt	Sat Jan 21 14:13:52 2017 +0100
+++ b/examples/font/CMakeLists.txt	Sun Jan 22 09:59:14 2017 +0100
@@ -1,7 +1,7 @@
 #
 # CMakeLists.txt -- CMake build system for malikania
 #
-# Copyright (c) 2013-2016 Malikania Authors
+# Copyright (c) 2013-2017 Malikania Authors
 #
 # Permission to use, copy, modify, and/or distribute this software for any
 # purpose with or without fee is hereby granted, provided that the above
@@ -16,10 +16,8 @@
 # OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 #
 
-malikania_create_test(
-    NAME font
+malikania_define_example(
+    TARGET font
     LIBRARIES libmlk-client
     SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/main.cpp
-    RESOURCES
-        resources/DejaVuSans.ttf
 )
--- a/examples/font/main.cpp	Sat Jan 21 14:13:52 2017 +0100
+++ b/examples/font/main.cpp	Sun Jan 22 09:59:14 2017 +0100
@@ -1,7 +1,7 @@
 /*
  * main.cpp -- test Font
  *
- * Copyright (c) 2013-2016 Malikania Authors
+ * Copyright (c) 2013-2017 Malikania Authors
  *
  * Permission to use, copy, modify, and/or distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
@@ -19,9 +19,6 @@
 #include <chrono>
 #include <thread>
 
-#define BOOST_TEST_MODULE "Font"
-#include <boost/test/unit_test.hpp>
-
 #include <malikania/client_resources_loader.hpp>
 #include <malikania/color.hpp>
 #include <malikania/font.hpp>
@@ -31,93 +28,98 @@
 
 using namespace std::chrono_literals;
 
-namespace {
-
-mlk::window window(400, 400);
-
-} // !namespace
-
-class test_font {
-protected:
-    mlk::directory_resources_locator m_locator;
-    mlk::client_resources_loader m_loader;
-    mlk::font m_font;
-
-public:
-    test_font()
-        : m_locator(SOURCE_DIRECTORY "/resources")
-        , m_loader(m_locator)
-        , m_font(m_loader.load_font("DejaVuSans.ttf", 10))
-    {
-        window.set_drawing_color(mlk::color("black"));
-        window.clear();
-    }
-};
-
-BOOST_FIXTURE_TEST_SUITE(test_font_suite, test_font)
-
-BOOST_AUTO_TEST_CASE(topleft)
+void topleft(mlk::window& window, mlk::font& font)
 {
+    window.set_drawing_color(mlk::color("black"));
+    window.clear();
     window.set_drawing_color(mlk::color("white"));
-    window.draw_text("top left", m_font, mlk::point(10, 10));
+    window.draw_text("top left", font, mlk::point(10, 10));
     window.present();
 
     std::this_thread::sleep_for(1s);
 }
 
-BOOST_AUTO_TEST_CASE(topright)
+void topright(mlk::window& window, mlk::font& font)
 {
-    auto dim = m_font.clip("top right");
+    auto dim = font.clip("top right");
+
+    window.set_drawing_color(mlk::color("black"));
+    window.clear();
+    window.set_drawing_color(mlk::color("white"));
+    window.draw_text("top right", font, mlk::point(400 - dim.width() - 10, 10));
+    window.present();
 
+    std::this_thread::sleep_for(1s);
+}
+
+void bottomleft(mlk::window& window, mlk::font& font)
+{
+    auto dim = font.clip("bottom left");
+
+    window.set_drawing_color(mlk::color("black"));
+    window.clear();
     window.set_drawing_color(mlk::color("white"));
-    window.draw_text("top right", m_font, mlk::point(400 - dim.width() - 10, 10));
+    window.draw_text("bottom left", font, mlk::point(10, 400 - dim.height() - 10));
     window.present();
 
     std::this_thread::sleep_for(1s);
 }
 
-BOOST_AUTO_TEST_CASE(bottomleft)
+void bottomright(mlk::window& window, mlk::font& font)
 {
-    auto dim = m_font.clip("bottom left");
+    auto dim = font.clip("bottom right");
 
+    window.set_drawing_color(mlk::color("black"));
+    window.clear();
     window.set_drawing_color(mlk::color("white"));
-    window.draw_text("bottom left", m_font, mlk::point(10, 400 - dim.height() - 10));
+    window.draw_text("bottom right", font, mlk::point(400 - dim.width() - 10, 400 - dim.height() - 10));
     window.present();
 
     std::this_thread::sleep_for(1s);
 }
 
-BOOST_AUTO_TEST_CASE(bottomright)
+void center(mlk::window& window, mlk::font& font)
 {
-    auto dim = m_font.clip("bottom right");
+    auto dim = font.clip("center");
 
+    window.set_drawing_color(mlk::color("black"));
+    window.clear();
     window.set_drawing_color(mlk::color("white"));
-    window.draw_text("bottom right", m_font, mlk::point(400 - dim.width() - 10, 400 - dim.height() - 10));
+    window.draw_text("center", font, mlk::point(200 - (dim.width() / 2), 200 - (dim.height() -2)));
     window.present();
 
     std::this_thread::sleep_for(1s);
 }
 
-BOOST_AUTO_TEST_CASE(center)
+void center2(mlk::window& window, mlk::font& font)
 {
-    auto dim = m_font.clip("center");
-
-    window.set_drawing_color(mlk::color("white"));
-    window.draw_text("center", m_font, mlk::point(200 - (dim.width() / 2), 200 - (dim.height() -2)));
-    window.present();
+    auto dim = font.clip("The world is Malikania.");
 
-    std::this_thread::sleep_for(1s);
-}
-
-BOOST_AUTO_TEST_CASE(center2)
-{
-    auto dim = m_font.clip("The world is Malikania.");
-
+    window.set_drawing_color(mlk::color("black"));
+    window.clear();
     window.set_drawing_color(mlk::color("white"));
-    window.draw_text("The world is Malikania.", m_font, mlk::point(200 - (dim.width() / 2), 200 - (dim.height() -2)));
+    window.draw_text("The world is Malikania.", font, mlk::point(200 - (dim.width() / 2), 200 - (dim.height() -2)));
     window.present();
 
     std::this_thread::sleep_for(3s);
 }
 
-BOOST_AUTO_TEST_SUITE_END()
+int main()
+{
+    try {
+        mlk::window window(400, 400);
+        mlk::directory_resources_locator locator(SOURCE_DIRECTORY);
+        mlk::client_resources_loader loader(locator);
+        mlk::font font = loader.load_font("DejaVuSans.ttf", 10);
+
+        topleft(window, font);
+        topright(window, font);
+        bottomleft(window, font);
+        bottomright(window, font);
+        center(window, font);
+        center2(window, font);
+    } catch (const std::exception& ex) {
+        std::cerr << ex.what() << std::endl;
+        return 1;
+    }
+}
--- a/examples/image/CMakeLists.txt	Sat Jan 21 14:13:52 2017 +0100
+++ b/examples/image/CMakeLists.txt	Sun Jan 22 09:59:14 2017 +0100
@@ -1,7 +1,7 @@
 #
 # CMakeLists.txt -- CMake build system for malikania
 #
-# Copyright (c) 2013-2016 Malikania Authors
+# Copyright (c) 2013-2017 Malikania Authors
 #
 # Permission to use, copy, modify, and/or distribute this software for any
 # purpose with or without fee is hereby granted, provided that the above
@@ -16,13 +16,8 @@
 # OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 #
 
-malikania_create_test(
-    NAME image
+malikania_define_example(
+    TARGET image
     LIBRARIES libmlk-client
     SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/main.cpp
-    RESOURCES
-        resources/images/100x10.png
-        resources/images/10x100.png
-        resources/images/16x16.png
-        resources/images/smiley.png
 )
--- a/examples/image/main.cpp	Sat Jan 21 14:13:52 2017 +0100
+++ b/examples/image/main.cpp	Sun Jan 22 09:59:14 2017 +0100
@@ -1,7 +1,7 @@
 /*
  * main.cpp -- test Image
  *
- * Copyright (c) 2013-2016 Malikania Authors
+ * Copyright (c) 2013-2017 Malikania Authors
  *
  * Permission to use, copy, modify, and/or distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
@@ -19,9 +19,6 @@
 #include <chrono>
 #include <thread>
 
-#define BOOST_TEST_MODULE "Image"
-#include <boost/test/unit_test.hpp>
-
 #include <malikania/client_resources_loader.hpp>
 #include <malikania/image.hpp>
 #include <malikania/resources_locator.hpp>
@@ -29,72 +26,10 @@
 
 using namespace std::chrono_literals;
 
-namespace {
-
-mlk::window window(400, 400);
-
-} // !namespace
-
-class test_image {
-protected:
-    mlk::directory_resources_locator m_locator;
-    mlk::client_resources_loader m_loader;
-
-public:
-    test_image()
-        : m_locator(SOURCE_DIRECTORY "/resources")
-        , m_loader(m_locator)
-    {
-    }
-};
-
-BOOST_FIXTURE_TEST_SUITE(test_image_suite, test_image)
-
-BOOST_AUTO_TEST_CASE(image100x10)
+void draw(mlk::window& window, mlk::client_resources_loader& loader)
 {
     try {
-        auto image = m_loader.load_image("images/100x10.png");
-
-        BOOST_REQUIRE_EQUAL(100U, image.size().width());
-        BOOST_REQUIRE_EQUAL(10U, image.size().height());
-    } catch (const std::exception &ex) {
-        BOOST_FAIL(ex.what());
-    }
-}
-
-BOOST_AUTO_TEST_CASE(image16x16)
-{
-    try {
-        auto image = m_loader.load_image("images/16x16.png");
-
-        BOOST_REQUIRE_EQUAL(16U, image.size().width());
-        BOOST_REQUIRE_EQUAL(16U, image.size().height());
-    } catch (const std::exception &ex) {
-        BOOST_FAIL(ex.what());
-    }
-}
-
-BOOST_AUTO_TEST_CASE(image10x100)
-{
-    try {
-        auto image = m_loader.load_image("images/10x100.png");
-
-        BOOST_REQUIRE_EQUAL(10U, image.size().width());
-        BOOST_REQUIRE_EQUAL(100U, image.size().height());
-    } catch (const std::exception &ex) {
-        BOOST_FAIL(ex.what());
-    }
-}
-
-BOOST_AUTO_TEST_CASE(notfound)
-{
-    BOOST_REQUIRE_THROW(m_loader.load_image("image-not-found"), std::exception);
-}
-
-BOOST_AUTO_TEST_CASE(draw)
-{
-    try {
-        auto image = m_loader.load_image("images/smiley.png");
+        auto image = loader.load_image("images/smiley.png");
         auto x = (400 / 2) - (image.size().width() / 2);
         auto y = (400 / 2) - (image.size().height() / 2);
 
@@ -104,8 +39,21 @@
 
         std::this_thread::sleep_for(3s);
     } catch (const std::exception &ex) {
-        BOOST_FAIL(ex.what());
+        std::cerr << ex.what() << std::endl;
+        std::exit(1);
     }
 }
 
-BOOST_AUTO_TEST_SUITE_END()
+int main()
+{
+    try {
+        mlk::window window(400, 400);
+        mlk::directory_resources_locator locator(SOURCE_DIRECTORY);
+        mlk::client_resources_loader loader(locator);
+
+        draw(window, loader);
+    } catch (const std::exception& ex) {
+        std::cerr << ex.what() << std::endl;
+        return 1;
+    }
+}
Binary file examples/image/resources/images/100x10.png has changed
Binary file examples/image/resources/images/10x100.png has changed
Binary file examples/image/resources/images/16x16.png has changed
Binary file examples/image/resources/images/smiley.xcf has changed
--- a/examples/js-animation/CMakeLists.txt	Sat Jan 21 14:13:52 2017 +0100
+++ b/examples/js-animation/CMakeLists.txt	Sun Jan 22 09:59:14 2017 +0100
@@ -1,7 +1,7 @@
 #
 # CMakeLists.txt -- CMake build system for malikania
 #
-# Copyright (c) 2013-2016 Malikania Authors
+# Copyright (c) 2013-2017 Malikania Authors
 #
 # Permission to use, copy, modify, and/or distribute this software for any
 # purpose with or without fee is hereby granted, provided that the above
@@ -16,12 +16,8 @@
 # OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 #
 
-malikania_create_test(
-    NAME js-animation
+malikania_define_example(
+    TARGET js-animation
     LIBRARIES libmlk-client-js
     SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/main.cpp
-    RESOURCES
-        resources/animations/margins.json
-        resources/images/margins.png
-        resources/sprites/margins.json
 )
--- a/examples/js-animation/main.cpp	Sat Jan 21 14:13:52 2017 +0100
+++ b/examples/js-animation/main.cpp	Sun Jan 22 09:59:14 2017 +0100
@@ -1,7 +1,7 @@
 /*
  * main.cpp -- test Animation (JavaScript binding)
  *
- * Copyright (c) 2013-2016 Malikania Authors
+ * Copyright (c) 2013-2017 Malikania Authors
  *
  * Permission to use, copy, modify, and/or distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
@@ -19,9 +19,6 @@
 #include <chrono>
 #include <thread>
 
-#define BOOST_TEST_MODULE "Javascript Animation"
-#include <boost/test/unit_test.hpp>
-
 #include <malikania/js_client_resources_loader.hpp>
 #include <malikania/js_animation.hpp>
 #include <malikania/js_animator.hpp>
@@ -30,31 +27,20 @@
 
 using namespace std::chrono_literals;
 
-class test_animation {
-protected:
-    mlk::directory_resources_locator m_locator;
-    mlk::client_resources_loader m_loader;
-    dukx_context m_ctx;
+int main()
+{
+    try {
+        mlk::directory_resources_locator locator(SOURCE_DIRECTORY);
+        mlk::client_resources_loader loader(locator);
+        dukx_context m_ctx;
 
-public:
-    test_animation()
-        : m_locator(SOURCE_DIRECTORY "/resources")
-        , m_loader(m_locator)
-    {
         duk_push_object(m_ctx);
         duk_put_global_string(m_ctx, "Malikania");
         mlk::dukx_load_animation(m_ctx);
         mlk::dukx_load_animator(m_ctx);
         mlk::dukx_load_window(m_ctx);
-        dukx_put_client_loader(m_ctx, m_loader);
-    }
-};
+        dukx_put_client_loader(m_ctx, loader);
 
-BOOST_FIXTURE_TEST_SUITE(test_animation_suite, test_animation)
-
-BOOST_AUTO_TEST_CASE(basic)
-{
-    try {
         auto ret = duk_peval_string(m_ctx,
             "w = new Malikania.Window();"
             "a = new Malikania.Animation('animations/margins.json');"
@@ -83,8 +69,7 @@
 
         std::this_thread::sleep_for(3s);
     } catch (const std::exception &ex) {
-        BOOST_FAIL(ex.what());
+        std::cerr << ex.what() << std::endl;
+        return 1;
     }
 }
-
-BOOST_AUTO_TEST_SUITE_END()
--- a/examples/js-font/CMakeLists.txt	Sat Jan 21 14:13:52 2017 +0100
+++ b/examples/js-font/CMakeLists.txt	Sun Jan 22 09:59:14 2017 +0100
@@ -1,7 +1,7 @@
 #
 # CMakeLists.txt -- CMake build system for malikania
 #
-# Copyright (c) 2013-2016 Malikania Authors
+# Copyright (c) 2013-2017 Malikania Authors
 #
 # Permission to use, copy, modify, and/or distribute this software for any
 # purpose with or without fee is hereby granted, provided that the above
@@ -16,10 +16,8 @@
 # OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 #
 
-malikania_create_test(
-    NAME js-font
+malikania_define_example(
+    TARGET js-font
     LIBRARIES libmlk-client-js
     SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/main.cpp
-    RESOURCES
-        resources/DejaVuSans.ttf
 )
--- a/examples/js-font/main.cpp	Sat Jan 21 14:13:52 2017 +0100
+++ b/examples/js-font/main.cpp	Sun Jan 22 09:59:14 2017 +0100
@@ -1,7 +1,7 @@
 /*
  * main.cpp -- test Font (JavaScript binding)
  *
- * Copyright (c) 2013-2016 Malikania Authors
+ * Copyright (c) 2013-2017 Malikania Authors
  *
  * Permission to use, copy, modify, and/or distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
@@ -19,9 +19,6 @@
 #include <chrono>
 #include <thread>
 
-#define BOOST_TEST_MODULE "Javascript Font"
-#include <boost/test/unit_test.hpp>
-
 #include <malikania/js_client_resources_loader.hpp>
 #include <malikania/js_font.hpp>
 #include <malikania/js_window.hpp>
@@ -29,50 +26,43 @@
 
 using namespace std::chrono_literals;
 
-class test_font {
-protected:
-    mlk::directory_resources_locator m_locator;
-    mlk::client_resources_loader m_loader;
-    dukx_context m_ctx;
+void basic(dukx_context& ctx)
+{
+    auto ret = duk_peval_string(ctx,
+        "w = new Malikania.Window();"
+        "f = new Malikania.Font('DejaVuSans.ttf', 10);"
+        "w.setDrawingColor('lightskyblue');"
+        "w.clear();"
+        "s = 'The world is Malikania.';"
+        "c = f.clip(s);"
+        "w.setDrawingColor('white');"
+        "w.drawText(s, f, { x: 320 - (c.width / 2), y: 240 - (c.height / 2) });"
+        "w.present();"
+    );
 
-public:
-    test_font()
-        : m_locator(SOURCE_DIRECTORY "/resources")
-        , m_loader(m_locator)
-    {
-        duk_push_object(m_ctx);
-        duk_put_global_string(m_ctx, "Malikania");
-        dukx_put_client_loader(m_ctx, m_loader);
-        mlk::dukx_load_font(m_ctx);
-        mlk::dukx_load_window(m_ctx);
+    if (ret != 0) {
+        throw dukx_get_exception(ctx, -1);
     }
-};
 
-BOOST_FIXTURE_TEST_SUITE(test_font_suite, test_font)
+    std::this_thread::sleep_for(3s);
+}
 
-BOOST_AUTO_TEST_CASE(basic)
+int main()
 {
     try {
-        auto ret = duk_peval_string(m_ctx,
-            "w = new Malikania.Window();"
-            "f = new Malikania.Font('DejaVuSans.ttf', 10);"
-            "w.setDrawingColor('lightskyblue');"
-            "w.clear();"
-            "s = 'The world is Malikania.';"
-            "c = f.clip(s);"
-            "w.setDrawingColor('white');"
-            "w.drawText(s, f, { x: 320 - (c.width / 2), y: 240 - (c.height / 2) });"
-            "w.present();"
-        );
+        mlk::directory_resources_locator locator(SOURCE_DIRECTORY);
+        mlk::client_resources_loader loader(locator);
+        dukx_context ctx;
 
-        if (ret != 0) {
-            throw dukx_get_exception(m_ctx, -1);
-        }
+        duk_push_object(ctx);
+        duk_put_global_string(ctx, "Malikania");
+        dukx_put_client_loader(ctx, loader);
+        mlk::dukx_load_font(ctx);
+        mlk::dukx_load_window(ctx);
 
-        std::this_thread::sleep_for(3s);
-    } catch (const std::exception &ex) {
-        BOOST_FAIL(ex.what());
+        basic(ctx);
+    } catch (const std::exception& ex) {
+        std::cerr << ex.what() << std::endl;
+        return 1;
     }
 }
-
-BOOST_AUTO_TEST_SUITE_END()
--- a/examples/js-image/CMakeLists.txt	Sat Jan 21 14:13:52 2017 +0100
+++ b/examples/js-image/CMakeLists.txt	Sun Jan 22 09:59:14 2017 +0100
@@ -1,7 +1,7 @@
 #
 # CMakeLists.txt -- CMake build system for malikania
 #
-# Copyright (c) 2013-2016 Malikania Authors
+# Copyright (c) 2013-2017 Malikania Authors
 #
 # Permission to use, copy, modify, and/or distribute this software for any
 # purpose with or without fee is hereby granted, provided that the above
@@ -16,10 +16,8 @@
 # OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 #
 
-malikania_create_test(
-    NAME js-image
+malikania_define_example(
+    TARGET js-image
     LIBRARIES libmlk-client-js
     SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/main.cpp
-    RESOURCES
-        resources/images/smiley.png
 )
--- a/examples/js-image/main.cpp	Sat Jan 21 14:13:52 2017 +0100
+++ b/examples/js-image/main.cpp	Sun Jan 22 09:59:14 2017 +0100
@@ -1,7 +1,7 @@
 /*
  * main.cpp -- test Image (JavaScript binding)
  *
- * Copyright (c) 2013-2016 Malikania Authors
+ * Copyright (c) 2013-2017 Malikania Authors
  *
  * Permission to use, copy, modify, and/or distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
@@ -19,9 +19,6 @@
 #include <chrono>
 #include <thread>
 
-#define BOOST_TEST_MODULE "Javacript Image"
-#include <boost/test/unit_test.hpp>
-
 #include <malikania/js_client_resources_loader.hpp>
 #include <malikania/js_image.hpp>
 #include <malikania/js_window.hpp>
@@ -29,93 +26,59 @@
 
 using namespace std::chrono_literals;
 
-class test_image {
-protected:
-    mlk::directory_resources_locator m_locator;
-    mlk::client_resources_loader m_loader;
-    dukx_context m_ctx;
-
-public:
-    test_image()
-        : m_locator(SOURCE_DIRECTORY "/resources")
-        , m_loader(m_locator)
-    {
-        duk_push_object(m_ctx);
-        duk_put_global_string(m_ctx, "Malikania");
-        mlk::dukx_load_image(m_ctx);
-        mlk::dukx_load_window(m_ctx);
-        dukx_put_client_loader(m_ctx, m_loader);
-    }
-};
-
-BOOST_FIXTURE_TEST_SUITE(test_image_suite, test_image)
+void basic(dukx_context& ctx)
+{
+    auto ret = duk_peval_string(ctx,
+        "w = new Malikania.Window();"
+        "i = new Malikania.Image('images/smiley.png');"
+        "w.setDrawingColor('lightskyblue');"
+        "w.clear();"
+        "i.draw(w, { x: 320 - 16, y: 240 - 16 });"
+        "w.present();"
+    );
 
-BOOST_AUTO_TEST_CASE(size)
-{
-    try {
-        auto ret = duk_peval_string(m_ctx,
-            "i = new Malikania.Image('images/smiley.png');"
-            "w = i.size.width;"
-            "h = i.size.height;"
-        );
+    if (ret != 0) {
+        throw dukx_get_exception(ctx, -1);
+    }
 
-        if (ret != 0) {
-            throw dukx_get_exception(m_ctx, -1);
-        }
-
-        duk_get_global_string(m_ctx, "w");
-        BOOST_REQUIRE_EQUAL(32U, duk_to_uint(m_ctx, -1));
-        duk_pop(m_ctx);
-        duk_get_global_string(m_ctx, "h");
-        BOOST_REQUIRE_EQUAL(32U, duk_to_uint(m_ctx, -1));
-        duk_pop(m_ctx);
-    } catch (const std::exception &ex) {
-        BOOST_FAIL(ex.what());
-    }
+    std::this_thread::sleep_for(3s);
 }
 
-BOOST_AUTO_TEST_CASE(basic)
+void stretch(dukx_context& ctx)
 {
-    try {
-        auto ret = duk_peval_string(m_ctx,
-            "w = new Malikania.Window();"
-            "i = new Malikania.Image('images/smiley.png');"
-            "w.setDrawingColor('lightskyblue');"
-            "w.clear();"
-            "i.draw(w, { x: 320 - 16, y: 240 - 16 });"
-            "w.present();"
-        );
+    auto ret = duk_peval_string(ctx,
+        "w = new Malikania.Window();"
+        "i = new Malikania.Image('images/smiley.png');"
+        "w.setDrawingColor('lightskyblue');"
+        "w.clear();"
+        "i.draw(w, null, { x: 10, y: 10, width: 620, height: 460 });"
+        "w.present();"
+    );
 
-        if (ret != 0) {
-            throw dukx_get_exception(m_ctx, -1);
-        }
+    if (ret != 0) {
+        throw dukx_get_exception(ctx, -1);
+    }
 
-        std::this_thread::sleep_for(3s);
-    } catch (const std::exception &ex) {
-        BOOST_FAIL(ex.what());
-    }
+    std::this_thread::sleep_for(3s);
 }
 
-BOOST_AUTO_TEST_CASE(stretch)
+int main()
 {
     try {
-        auto ret = duk_peval_string(m_ctx,
-            "w = new Malikania.Window();"
-            "i = new Malikania.Image('images/smiley.png');"
-            "w.setDrawingColor('lightskyblue');"
-            "w.clear();"
-            "i.draw(w, null, { x: 10, y: 10, width: 620, height: 460 });"
-            "w.present();"
-        );
+        mlk::directory_resources_locator locator(SOURCE_DIRECTORY);
+        mlk::client_resources_loader loader(locator);
+        dukx_context ctx;
 
-        if (ret != 0) {
-            throw dukx_get_exception(m_ctx, -1);
-        }
+        duk_push_object(ctx);
+        duk_put_global_string(ctx, "Malikania");
+        mlk::dukx_load_image(ctx);
+        mlk::dukx_load_window(ctx);
+        dukx_put_client_loader(ctx, loader);
 
-        std::this_thread::sleep_for(3s);
-    } catch (const std::exception &ex) {
-        BOOST_FAIL(ex.what());
+        basic(ctx);
+        stretch(ctx);
+    } catch (const std::exception& ex) {
+        std::cerr << ex.what() << std::endl;
+        return 1;
     }
 }
-
-BOOST_AUTO_TEST_SUITE_END()
--- a/examples/js-sprite/CMakeLists.txt	Sat Jan 21 14:13:52 2017 +0100
+++ b/examples/js-sprite/CMakeLists.txt	Sun Jan 22 09:59:14 2017 +0100
@@ -16,11 +16,8 @@
 # OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 #
 
-malikania_create_test(
-    NAME js-sprite
+malikania_define_example(
+    TARGET js-sprite
     LIBRARIES libmlk-client-js
     SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/main.cpp
-    RESOURCES
-        resources/images/margins.png
-        resources/sprites/margins.json
 )
--- a/examples/js-sprite/main.cpp	Sat Jan 21 14:13:52 2017 +0100
+++ b/examples/js-sprite/main.cpp	Sun Jan 22 09:59:14 2017 +0100
@@ -1,7 +1,7 @@
 /*
  * main.cpp -- test Sprite (JavaScript binding)
  *
- * Copyright (c) 2013-2016 Malikania Authors
+ * Copyright (c) 2013-2017 Malikania Authors
  *
  * Permission to use, copy, modify, and/or distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
@@ -19,183 +19,59 @@
 #include <chrono>
 #include <thread>
 
-#define BOOST_TEST_MODULE "Javascript Sprite"
-#include <boost/test/unit_test.hpp>
-
 #include <malikania/js_client_resources_loader.hpp>
 #include <malikania/js_image.hpp>
 #include <malikania/js_sprite.hpp>
 #include <malikania/js_window.hpp>
 #include <malikania/resources_locator.hpp>
 
-using namespace mlk;
-
 using namespace std::chrono_literals;
 
-class test_sprite {
-protected:
-    directory_resources_locator m_locator;
-    client_resources_loader m_loader;
-    dukx_context m_ctx;
-
-public:
-    test_sprite()
-        : m_locator(SOURCE_DIRECTORY "/resources")
-        , m_loader(m_locator)
-    {
-        duk_push_object(m_ctx);
-        duk_put_global_string(m_ctx, "Malikania");
-        mlk::dukx_load_image(m_ctx);
-        mlk::dukx_load_sprite(m_ctx);
-        mlk::dukx_load_window(m_ctx);
-        dukx_put_client_loader(m_ctx, m_loader);
-    }
-};
-
-BOOST_FIXTURE_TEST_SUITE(test_sprite_suite, test_sprite)
-
-BOOST_AUTO_TEST_CASE(cell)
+void basic(dukx_context& ctx)
 {
-    try {
-        auto ret = duk_peval_string(m_ctx,
-            "s = new Malikania.Sprite('sprites/margins.json');"
-            "w = s.cell.width;"
-            "h = s.cell.height;"
-        );
-
-        if (ret != 0) {
-            throw dukx_get_exception(m_ctx, -1);
-        }
+    auto ret = duk_peval_string(ctx,
+        "w = new Malikania.Window();"
+        "s = new Malikania.Sprite('sprites/margins.json');"
+        "c = 0;"
+    );
 
-        duk_get_global_string(m_ctx, "w");
-        BOOST_REQUIRE_EQUAL(32U, duk_to_uint(m_ctx, -1));
-        duk_pop(m_ctx);
-        duk_get_global_string(m_ctx, "h");
-        BOOST_REQUIRE_EQUAL(32U, duk_to_uint(m_ctx, -1));
-        duk_pop(m_ctx);
-    } catch (const std::exception &ex) {
-        BOOST_FAIL(ex.what());
+    if (ret != 0) {
+        throw dukx_get_exception(ctx, -1);
     }
-}
-
-BOOST_AUTO_TEST_CASE(columns)
-{
-    try {
-        auto ret = duk_peval_string(m_ctx,
-            "s = new Malikania.Sprite('sprites/margins.json');"
-            "n = s.columns;"
-        );
 
-        if (ret != 0) {
-            throw dukx_get_exception(m_ctx, -1);
-        }
-
-        duk_get_global_string(m_ctx, "n");
-        BOOST_REQUIRE_EQUAL(4U, duk_to_uint(m_ctx, -1));
-        duk_pop(m_ctx);
-    } catch (const std::exception &ex) {
-        BOOST_FAIL(ex.what());
-    }
-}
-
-BOOST_AUTO_TEST_CASE(margins)
-{
-    try {
-        auto ret = duk_peval_string(m_ctx,
-            "s = new Malikania.Sprite('sprites/margins.json');"
-            "w = s.margins.width;"
-            "h = s.margins.height;"
+    for (unsigned c = 0; c < 12; ++c) {
+        auto ret = duk_peval_string(ctx,
+            "w.setDrawingColor('lightskyblue');"
+            "w.clear();"
+            "s.draw(w, c++, { x: 320 - 16, y: 240 - 16 });"
+            "w.present();"
         );
 
         if (ret != 0) {
-            throw dukx_get_exception(m_ctx, -1);
+            throw dukx_get_exception(ctx, -1);
         }
 
-        duk_get_global_string(m_ctx, "w");
-        BOOST_REQUIRE_EQUAL(4U, duk_to_uint(m_ctx, -1));
-        duk_pop(m_ctx);
-        duk_get_global_string(m_ctx, "h");
-        BOOST_REQUIRE_EQUAL(6U, duk_to_uint(m_ctx, -1));
-        duk_pop(m_ctx);
-    } catch (const std::exception &ex) {
-        BOOST_FAIL(ex.what());
-    }
-}
-
-BOOST_AUTO_TEST_CASE(rows)
-{
-    try {
-        auto ret = duk_peval_string(m_ctx,
-            "s = new Malikania.Sprite('sprites/margins.json');"
-            "n = s.rows;"
-        );
-
-        if (ret != 0) {
-            throw dukx_get_exception(m_ctx, -1);
-        }
-
-        duk_get_global_string(m_ctx, "n");
-        BOOST_REQUIRE_EQUAL(3U, duk_to_uint(m_ctx, -1));
-        duk_pop(m_ctx);
-    } catch (const std::exception &ex) {
-        BOOST_FAIL(ex.what());
+        std::this_thread::sleep_for(1s);
     }
 }
 
-BOOST_AUTO_TEST_CASE(space)
-{
-    try {
-        auto ret = duk_peval_string(m_ctx,
-            "s = new Malikania.Sprite('sprites/margins.json');"
-            "w = s.space.width;"
-            "h = s.space.height;"
-        );
-
-        if (ret != 0) {
-            throw dukx_get_exception(m_ctx, -1);
-        }
-
-        duk_get_global_string(m_ctx, "w");
-        BOOST_REQUIRE_EQUAL(2U, duk_to_uint(m_ctx, -1));
-        duk_pop(m_ctx);
-        duk_get_global_string(m_ctx, "h");
-        BOOST_REQUIRE_EQUAL(3U, duk_to_uint(m_ctx, -1));
-        duk_pop(m_ctx);
-    } catch (const std::exception &ex) {
-        BOOST_FAIL(ex.what());
-    }
-}
-
-BOOST_AUTO_TEST_CASE(basic)
+int main()
 {
     try {
-        auto ret = duk_peval_string(m_ctx,
-            "w = new Malikania.Window();"
-            "s = new Malikania.Sprite('sprites/margins.json');"
-            "c = 0;"
-        );
-
-        if (ret != 0) {
-            throw dukx_get_exception(m_ctx, -1);
-        }
+        mlk::directory_resources_locator locator(SOURCE_DIRECTORY);
+        mlk::client_resources_loader loader(locator);
+        dukx_context ctx;
 
-        for (unsigned c = 0; c < 12; ++c) {
-            auto ret = duk_peval_string(m_ctx,
-                "w.setDrawingColor('lightskyblue');"
-                "w.clear();"
-                "s.draw(w, c++, { x: 320 - 16, y: 240 - 16 });"
-                "w.present();"
-            );
+        duk_push_object(ctx);
+        duk_put_global_string(ctx, "Malikania");
+        mlk::dukx_load_image(ctx);
+        mlk::dukx_load_sprite(ctx);
+        mlk::dukx_load_window(ctx);
+        dukx_put_client_loader(ctx, loader);
 
-            if (ret != 0) {
-                throw dukx_get_exception(m_ctx, -1);
-            }
-
-            std::this_thread::sleep_for(1s);
-        }
-    } catch (const std::exception &ex) {
-        BOOST_FAIL(ex.what());
+        basic(ctx);
+    } catch (const std::exception& ex) {
+        std::cerr << ex.what() << std::endl;
+        return 1;
     }
 }
-
-BOOST_AUTO_TEST_SUITE_END()
--- a/examples/js-window/CMakeLists.txt	Sat Jan 21 14:13:52 2017 +0100
+++ b/examples/js-window/CMakeLists.txt	Sun Jan 22 09:59:14 2017 +0100
@@ -1,7 +1,7 @@
 #
 # CMakeLists.txt -- CMake build system for malikania
 #
-# Copyright (c) 2013-2016 Malikania Authors
+# Copyright (c) 2013-2017 Malikania Authors
 #
 # Permission to use, copy, modify, and/or distribute this software for any
 # purpose with or without fee is hereby granted, provided that the above
@@ -16,8 +16,8 @@
 # OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 #
 
-malikania_create_test(
-    NAME js-window
+malikania_define_example(
+    TARGET js-window
     LIBRARIES libmlk-client-js
     SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/main.cpp
 )
--- a/examples/js-window/main.cpp	Sat Jan 21 14:13:52 2017 +0100
+++ b/examples/js-window/main.cpp	Sun Jan 22 09:59:14 2017 +0100
@@ -1,7 +1,7 @@
 /*
  * main.cpp -- test Window (JavaScript binding)
  *
- * Copyright (c) 2013-2016 Malikania Authors
+ * Copyright (c) 2013-2017 Malikania Authors
  *
  * Permission to use, copy, modify, and/or distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
@@ -17,71 +17,60 @@
  */
 
 #include <chrono>
+#include <iostream>
 #include <thread>
 
-#define BOOST_TEST_MODULE "Javascript Window"
-#include <boost/test/unit_test.hpp>
-
 #include <malikania/js_window.hpp>
 
-using namespace mlk;
 using namespace std::chrono_literals;
 
-class test_window {
-protected:
-    dukx_context m_ctx;
+void basic(dukx_context& ctx)
+{
+    auto ret = duk_peval_string(ctx,
+        "w = new Malikania.Window();"
+        "w.setDrawingColor('lightskyblue');"
+        "w.clear();"
+        "w.present();"
+    );
+
+    if (ret != 0) {
+        throw dukx_get_exception(ctx, -1);
+    }
+
+    std::this_thread::sleep_for(3s);
+}
 
-public:
-    test_window()
-    {
-        duk_push_object(m_ctx);
-        duk_put_global_string(m_ctx, "Malikania");
-        mlk::dukx_load_window(m_ctx);
+void rect(dukx_context& ctx)
+{
+    auto ret = duk_peval_string(ctx,
+        "w = new Malikania.Window();"
+        "w.setDrawingColor('lightskyblue');"
+        "w.clear();"
+        "w.setDrawingColor('white');"
+        "w.drawRectangle({ x: 10, y: 10, width: 10, height: 10 });"
+        "w.present();"
+    );
+
+    if (ret != 0) {
+        throw dukx_get_exception(ctx, -1);
     }
-};
 
-BOOST_FIXTURE_TEST_SUITE(test_window_suite, test_window)
+    std::this_thread::sleep_for(3s);
+}
 
-BOOST_AUTO_TEST_CASE(basic)
+int main()
 {
     try {
-        auto ret = duk_peval_string(m_ctx,
-            "w = new Malikania.Window();"
-            "w.setDrawingColor('lightskyblue');"
-            "w.clear();"
-            "w.present();"
-        );
+        dukx_context ctx;
+
+        duk_push_object(ctx);
+        duk_put_global_string(ctx, "Malikania");
+        mlk::dukx_load_window(ctx);
 
-        if (ret != 0) {
-            throw dukx_get_exception(m_ctx, -1);
-        }
-
-        std::this_thread::sleep_for(3s);
-    } catch (const std::exception &ex) {
-        BOOST_FAIL(ex.what());
+        basic(ctx);
+        rect(ctx);
+    } catch (const std::exception& ex) {
+        std::cerr << ex.what() << std::endl;
+        return 1;
     }
 }
-
-BOOST_AUTO_TEST_CASE(rect)
-{
-    try {
-        auto ret = duk_peval_string(m_ctx,
-            "w = new Malikania.Window();"
-            "w.setDrawingColor('lightskyblue');"
-            "w.clear();"
-            "w.setDrawingColor('white');"
-            "w.drawRectangle({ x: 10, y: 10, width: 10, height: 10 });"
-            "w.present();"
-        );
-
-        if (ret != 0) {
-            throw dukx_get_exception(m_ctx, -1);
-        }
-
-        std::this_thread::sleep_for(3s);
-    } catch (const std::exception &ex) {
-        BOOST_FAIL(ex.what());
-    }
-}
-
-BOOST_AUTO_TEST_SUITE_END()
--- a/examples/sprite/CMakeLists.txt	Sat Jan 21 14:13:52 2017 +0100
+++ b/examples/sprite/CMakeLists.txt	Sun Jan 22 09:59:14 2017 +0100
@@ -1,7 +1,7 @@
 #
 # CMakeLists.txt -- CMake build system for malikania
 #
-# Copyright (c) 2013-2016 Malikania Authors
+# Copyright (c) 2013-2017 Malikania Authors
 #
 # Permission to use, copy, modify, and/or distribute this software for any
 # purpose with or without fee is hereby granted, provided that the above
@@ -16,21 +16,8 @@
 # OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 #
 
-malikania_create_test(
-    NAME sprite
+malikania_define_example(
+    TARGET sprite
     LIBRARIES libmlk-client
     SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/main.cpp
-    RESOURCES
-        resources/images/mokodemo.png
-        resources/images/margins.png
-        resources/sprites/no-property-cell.json
-        resources/sprites/no-property-image.json
-        resources/sprites/image-not-found.json
-        resources/sprites/not-object.json
-        resources/sprites/property-image-not-string.json
-        resources/sprites/property-cell-not-array.json
-        resources/sprites/property-cell-not-array2.json
-        resources/sprites/simple.json
-        resources/sprites/margins.json
 )
-
--- a/examples/sprite/main.cpp	Sat Jan 21 14:13:52 2017 +0100
+++ b/examples/sprite/main.cpp	Sun Jan 22 09:59:14 2017 +0100
@@ -1,7 +1,7 @@
 /*
  * main.cpp -- test Sprite
  *
- * Copyright (c) 2013-2016 Malikania Authors
+ * Copyright (c) 2013-2017 Malikania Authors
  *
  * Permission to use, copy, modify, and/or distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
@@ -20,9 +20,6 @@
 #include <thread>
 #include <exception>
 
-#define BOOST_TEST_MODULE "Sprite"
-#include <boost/test/unit_test.hpp>
-
 #include <malikania/client_resources_loader.hpp>
 #include <malikania/resources_locator.hpp>
 #include <malikania/sprite.hpp>
@@ -30,162 +27,32 @@
 
 using namespace std::chrono_literals;
 
-namespace {
-
-mlk::window window(400, 400);
-
-} // !namespace
-
-class test_sprite {
-protected:
-    mlk::directory_resources_locator m_locator;
-    mlk::client_resources_loader m_loader;
-
-public:
-    test_sprite()
-        : m_locator(SOURCE_DIRECTORY "/resources")
-        , m_loader(m_locator)
-    {
-    }
-};
-
-BOOST_FIXTURE_TEST_SUITE(test_sprite_suite, test_sprite)
-
-/*
- * Missing properties.
- * ------------------------------------------------------------------
- */
-
-BOOST_AUTO_TEST_SUITE(missing_properties)
-
-BOOST_AUTO_TEST_CASE(image)
-{
-    BOOST_REQUIRE_THROW(
-        m_loader.load_sprite("sprites/no-property-image.json"),
-        std::exception
-    );
-}
-
-BOOST_AUTO_TEST_CASE(cell)
-{
-    BOOST_REQUIRE_THROW(
-        m_loader.load_sprite("sprites/no-property-cell.json"),
-        std::exception
-    );
-}
-
-BOOST_AUTO_TEST_SUITE_END()
-
-/*
- * Invalid properties.
- * ------------------------------------------------------------------
- */
-
-BOOST_AUTO_TEST_SUITE(invalid_properties)
-
-BOOST_AUTO_TEST_CASE(image_not_string)
+void draw(mlk::window& window, mlk::client_resources_loader& loader)
 {
-    BOOST_REQUIRE_THROW(
-        m_loader.load_sprite("sprites/property-image-not-string.json"),
-        std::exception
-    );
-}
-
-BOOST_AUTO_TEST_CASE(cell_not_array)
-{
-    BOOST_REQUIRE_THROW(
-        m_loader.load_sprite("sprites/property-cell-not-array.json"),
-        std::exception
-    );
-}
-
-BOOST_AUTO_TEST_CASE(cell_not_array2)
-{
-    BOOST_REQUIRE_THROW(
-        m_loader.load_sprite("sprites/property-cell-not-array2.json"),
-        std::exception
-    );
-}
-
-BOOST_AUTO_TEST_SUITE_END()
-
-/*
- * Other errors.
- * ------------------------------------------------------------------
- */
-
-BOOST_AUTO_TEST_SUITE(miscellaneous_errors)
+    auto sprite = loader.load_sprite("sprites/margins.json");
+    auto total = sprite.rows() * sprite.columns();
+    auto x = (400 / 2) - (sprite.cell().width() / 2);
+    auto y = (400 / 2) - (sprite.cell().height() / 2);
 
-BOOST_AUTO_TEST_CASE(image_not_found)
-{
-    BOOST_REQUIRE_THROW(
-        m_loader.load_sprite("sprites/image-not-found.json"),
-        std::exception
-    );
-}
-
-BOOST_AUTO_TEST_CASE(not_object)
-{
-    BOOST_REQUIRE_THROW(
-        m_loader.load_sprite("sprites/not-object.json"),
-        std::exception
-    );
-}
+    for (unsigned c = 0; c < total; ++c) {
+        window.clear();
+        sprite.draw(window, c, mlk::point(x, y));
+        window.present();
 
-BOOST_AUTO_TEST_SUITE_END()
-
-/*
- * Valid sprites.
- * ------------------------------------------------------------------
- */
-
-BOOST_AUTO_TEST_SUITE(valid)
-
-BOOST_AUTO_TEST_CASE(standard)
-{
-    try {
-        auto sprite = m_loader.load_sprite("sprites/simple.json");
-
-        BOOST_REQUIRE_EQUAL(300U, sprite.cell().width());
-        BOOST_REQUIRE_EQUAL(300U, sprite.cell().height());
-    } catch (const std::exception &ex) {
-        BOOST_FAIL(ex.what());
+        std::this_thread::sleep_for(1s);
     }
 }
 
-BOOST_AUTO_TEST_CASE(margins)
-{
-    try {
-        auto sprite = m_loader.load_sprite("sprites/margins.json");
-
-        BOOST_REQUIRE_EQUAL(3U, sprite.rows());
-        BOOST_REQUIRE_EQUAL(4U, sprite.columns());
-    } catch (const std::exception &ex) {
-        BOOST_FAIL(ex.what());
-    }
-}
-
-BOOST_AUTO_TEST_CASE(draw)
+int main()
 {
     try {
-        auto sprite = m_loader.load_sprite("sprites/margins.json");
-
-        auto total = sprite.rows() * sprite.columns();
-        auto x = (400 / 2) - (sprite.cell().width() / 2);
-        auto y = (400 / 2) - (sprite.cell().height() / 2);
+        mlk::directory_resources_locator locator(SOURCE_DIRECTORY);
+        mlk::client_resources_loader loader(locator);
+        mlk::window window(400, 400);
 
-        for (unsigned c = 0; c < total; ++c) {
-            window.clear();
-            sprite.draw(window, c, mlk::point(x, y));
-            window.present();
-
-            std::this_thread::sleep_for(1s);
-        }
-    } catch (const std::exception &ex) {
-        BOOST_FAIL(ex.what());
+        draw(window, loader);
+    } catch (const std::exception& ex) {
+        std::cerr << ex.what() << std::endl;
+        return 1;
     }
 }
-
-BOOST_AUTO_TEST_SUITE_END()
-
-BOOST_AUTO_TEST_SUITE_END()
Binary file examples/sprite/resources/images/margins.xcf has changed
Binary file examples/sprite/resources/images/mokodemo.png has changed
--- a/examples/sprite/resources/sprites/image-not-found.json	Sat Jan 21 14:13:52 2017 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,4 +0,0 @@
-{
-  "image": "does-not-exist.png",
-  "cell": [ 0, 0 ]
-}
--- a/examples/sprite/resources/sprites/no-property-cell.json	Sat Jan 21 14:13:52 2017 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,3 +0,0 @@
-{
-  "image": "images/mokodemo.png"
-}
--- a/examples/sprite/resources/sprites/no-property-image.json	Sat Jan 21 14:13:52 2017 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,3 +0,0 @@
-{
-  "cell": [ 16, 16 ]
-}
--- a/examples/sprite/resources/sprites/not-object.json	Sat Jan 21 14:13:52 2017 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,2 +0,0 @@
-[
-]
--- a/examples/sprite/resources/sprites/property-cell-not-array.json	Sat Jan 21 14:13:52 2017 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,4 +0,0 @@
-{
-  "image": "images/mokodemo.png",
-  "cell": "hello"
-}
--- a/examples/sprite/resources/sprites/property-cell-not-array2.json	Sat Jan 21 14:13:52 2017 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,4 +0,0 @@
-{
-  "image": "images/mokodemo.png",
-  "cell": [ true, false ]
-}
--- a/examples/sprite/resources/sprites/property-image-not-string.json	Sat Jan 21 14:13:52 2017 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,4 +0,0 @@
-{
-  "image": 123,
-  "cell": [ 0, 0 ]
-}
--- a/examples/sprite/resources/sprites/simple.json	Sat Jan 21 14:13:52 2017 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,4 +0,0 @@
-{
-  "image": "images/mokodemo.png",
-  "cell": [ 300, 300 ]
-}