1. 4FIPS
  2. PHOTOS
  3. VIDEOS
  4. APPS
  5. CODE
  6. FORUMS
  7. ABOUT
/*
(c) 2004-14 Filip Stoklas, aka FipS, www.4FipS.com
THIS CODE IS FREE - LICENSED UNDER THE MIT LICENSE
*/

#include "fs_common.h"
#include "fs_common_type.h"
#include "fs_common_os.h"

#define FS_CHECK FS_ASSERT

// --- NARROW CAST ---

void test_narrow_cast() FS_NOEXCEPT
{
    // unsigned/unsigned:
    fs::narrow_cast<uint8_t>(uint16_t(0));
    fs::narrow_cast<uint8_t>(uint16_t(255));
    // fs::narrow_cast<uint8_t>(uint16_t(256)); // assert

    // signed/signed:
    fs::narrow_cast<int8_t>(int16_t(-128));
    fs::narrow_cast<int8_t>(int16_t(127));
    //fs::narrow_cast<int8_t>(int16_t(-129)); // assert
    //fs::narrow_cast<int8_t>(int16_t(128)); // assert

    // unsigned/signed
    fs::narrow_cast<uint8_t>(int16_t(0));
    fs::narrow_cast<uint8_t>(int16_t(255));
    // fs::narrow_cast<uint8_t>(int16_t(-1)); // assert
    // fs::narrow_cast<uint8_t>(int16_t(256)); // assert

    // signed/unsigned
    fs::narrow_cast<int8_t>(uint16_t(0));
    fs::narrow_cast<int8_t>(uint16_t(127));
    // fs::narrow_cast<int8_t>(uint16_t(128)); // assert
}

// --- YES/NO DIALOG ---

void test_yes_no_dialog() FS_NOEXCEPT
{
    FS_CHECK(fs::os::show_yes_no_dialog("show_yes_no_dialog() test", "Press 'Yes' to continue...", true));
    FS_CHECK(!fs::os::show_yes_no_dialog("show_yes_no_dialog() test", "Press 'No' to continue...", false));
}

// --- ASSERT ---

void test_assert() FS_NOEXCEPT
{
    const auto my_handler = [](
     const char *expr,
     const char *func,
     const char *file,
     int line
    ) FS_NOEXCEPT
    {
        printf("[o] ASSERT-TEST: '%s', '%s', %s(%d)\n", expr, func, file, line);
        return false;
    };

    const auto orig_handler = fs::assert::set_handler(my_handler);
    {
        FS_ASSERT(true);
        FS_ASSERT(false && "Something unexpected happened!");
    }
    fs::assert::set_handler(orig_handler);
}

// --- TRACE ---

void test_trace() FS_NOEXCEPT
{
    const auto my_handler = [](const char *text) FS_NOEXCEPT
    {
        printf("[o] TRACE-TEST: '%s'\n", text);
    };

    {
        FS_TRACE(("[o] Trace-test #%d!", 1));
        FS_TRACE(("[o] Trace-test #%d!", 2));
        FS_TRACE(("[o] Trace-test #%d!", 3));
    }

    const auto orig_handler = fs::trace::set_handler(my_handler);
    {
        FS_TRACE(("Trace #%d!", 4));
        FS_TRACE(("Trace #%d!", 5));
        FS_TRACE(("Trace #%d!", 6));
    }
    fs::trace::set_handler(orig_handler);
}

// --- PROBE ---

void test_probe() FS_NOEXCEPT
{
    const auto my_handler = [](void *ctx, const char *key, double val) FS_NOEXCEPT
    {
        printf("[o] PROBE-TEST: '%s' %g\n", key, val);
    };

    {
        FS_PROBE("x", 1.0);
        FS_PROBE("x", 2.0);
        FS_PROBE("x", 3.0);
    }

    const auto orig_handler = fs::probe::set_handler({my_handler, nullptr});
    {
        FS_PROBE("x", 1.0);
        FS_PROBE("x", 2.0);
        FS_PROBE("x", 3.0);
    }
    fs::probe::set_handler(orig_handler);
}

// --- ERROR ---

void test_error() FS_NOEXCEPT
{
    const auto my_handler = [](const fs::error::error &err) FS_NOEXCEPT
    {
        printf("[o] ERROR-TEST: '%s'\n", err.what());
        // normally, we would terminate here...
    };

    const auto orig_handler = fs::error::set_handler(my_handler);
    const auto orig_break = fs::error::enable_debug_break(false);
    {
        FS_ERROR(fs::error::error("Something unexpected happened!"));
    }
    fs::error::set_handler(orig_handler);
    fs::error::enable_debug_break(orig_break);
}

// --- INDEX ---

void test_index_t() FS_NOEXCEPT
{
    struct tag {};
    using index_type = fs::index_t<uint8_t, tag>;

    FS_CHECK(index_type::make(0).valid());
    FS_CHECK(index_type::make(5).valid());

    //FS_CHECK(index_type::make(999).valid()); // assert: overflow

    FS_CHECK(!index_type::make().valid());
    FS_CHECK(!index_type::make(index_type::make().pos()).valid());
}

void test_index() FS_NOEXCEPT
{
    struct tag {};
    using index_type = fs::index<uint8_t, tag>;

    FS_CHECK(index_type(0).valid());
    FS_CHECK(index_type(5).valid());

    //FS_CHECK(index_type(999).valid()); // assert: overflow

    FS_CHECK(!index_type().valid());
    FS_CHECK(!index_type(index_type().pos()).valid());
}

// --- HANDLE ---

void test_handle_t() FS_NOEXCEPT
{
    struct tag {};
    using handle_type = fs::handle_t<uint16_t, 8, tag>;

    FS_CHECK(handle_type::make(0, 5).valid());
    FS_CHECK(handle_type::make(5, 5).valid());

    FS_CHECK(!handle_type::make(0, 0).valid());
    FS_CHECK(!handle_type::make(5, 0).valid());

    FS_CHECK(!handle_type::make().valid());
}

void test_handle() FS_NOEXCEPT
{
    // TODO
}

// --- MAIN ---

int main(int argc, char *argv[])
{
    FS_TRACE(("[o] TEST: fs_test_common"));

    test_narrow_cast();
    test_yes_no_dialog();
    test_assert();
    test_trace();
    test_probe();
    test_error();
    test_index_t();
    test_index();
    test_handle_t();
    test_handle();

    return 0;
}