<commit_before>#include "application.hpp"

#include "controllers/accounts/accountcontroller.hpp"
#include "controllers/commands/commandcontroller.hpp"
#include "controllers/highlights/highlightcontroller.hpp"
#include "controllers/ignores/ignorecontroller.hpp"
#include "controllers/taggedusers/taggeduserscontroller.hpp"
#include "providers/twitch/pubsub.hpp"
#include "providers/twitch/twitchserver.hpp"
#include "singletons/emotemanager.hpp"
#include "singletons/fontmanager.hpp"
#include "singletons/loggingmanager.hpp"
#include "singletons/nativemessagingmanager.hpp"
#include "singletons/pathmanager.hpp"
#include "singletons/resourcemanager.hpp"
#include "singletons/settingsmanager.hpp"
#include "singletons/thememanager.hpp"
#include "singletons/windowmanager.hpp"
#include "util/posttothread.hpp"

#include <atomic>

using namespace chatterino::singletons;

namespace chatterino {

namespace {

bool isBigEndian()
{
    int test = 1;
    char *p = reinterpret_cast<char *>(&test);

    return p[0] == 0;
}

}  // namespace

static std::atomic<bool> isAppConstructed{false};
static std::atomic<bool> isAppInitialized{false};

static Application *staticApp = nullptr;

// this class is responsible for handling the workflow of Chatterino
// It will create the instances of the major classes, and connect their signals to each other

Application::Application(int _argc, char **_argv)
    : argc(_argc)
    , argv(_argv)
{
}

void Application::construct()
{
    assert(isAppConstructed == false);
    isAppConstructed = true;

    // 1. Instantiate all classes
    this->settings = new singletons::SettingManager;
    this->paths = singletons::PathManager::getInstance();
    this->themes = new singletons::ThemeManager;
    this->windows = new singletons::WindowManager;
    this->logging = new singletons::LoggingManager;
    this->commands = new controllers::commands::CommandController;
    this->highlights = new controllers::highlights::HighlightController;
    this->ignores = new controllers::ignores::IgnoreController;
    this->taggedUsers = new controllers::taggedusers::TaggedUsersController;
    this->accounts = new controllers::accounts::AccountController;
    this->emotes = new singletons::EmoteManager;
    this->fonts = new singletons::FontManager;
    this->resources = new singletons::ResourceManager;

    this->twitch.server = new providers::twitch::TwitchServer;
    this->twitch.pubsub = new providers::twitch::PubSub;
}

void Application::instantiate(int argc, char **argv)
{
    assert(staticApp == nullptr);

    staticApp = new Application(argc, argv);
}

void Application::initialize()
{
    assert(isAppInitialized == false);
    isAppInitialized = true;

    // 2. Initialize/load classes
    this->settings->initialize();

#ifdef Q_OS_WIN
#ifdef QT_DEBUG
#ifdef C_DEBUG_NM
    this->nativeMessaging->registerHost();
#endif
#else
    this->nativeMessaging->registerHost();
#endif
#endif

    this->settings->load();
    this->commands->load();
    this->logging->initialize();
    this->windows->initialize();

    this->resources->initialize();

    this->highlights->initialize();
    this->ignores->initialize();

    this->emotes->initialize();

    this->accounts->load();

    this->twitch.server->initialize();

    // XXX
    this->settings->updateWordTypeMask();

    this->nativeMessaging->openGuiMessageQueue();

    this->twitch.pubsub->sig.whisper.sent.connect([](const auto &msg) {
        debug::Log("WHISPER SENT LOL");  //
    });

    this->twitch.pubsub->sig.whisper.received.connect([](const auto &msg) {
        debug::Log("WHISPER RECEIVED LOL");  //
    });

    this->twitch.pubsub->sig.moderation.chatCleared.connect([this](const auto &action) {
        auto chan = this->twitch.server->getChannelOrEmptyByID(action.roomID);
        if (chan->isEmpty()) {
            return;
        }

        QString text = QString("%1 cleared the chat").arg(action.source.name);

        auto msg = messages::Message::createSystemMessage(text);
        util::postToThread([chan, msg] { chan->addMessage(msg); });
    });

    this->twitch.pubsub->sig.moderation.modeChanged.connect([this](const auto &action) {
        auto chan = this->twitch.server->getChannelOrEmptyByID(action.roomID);
        if (chan->isEmpty()) {
            return;
        }

        QString text =
            QString("%1 turned %2 %3 mode")  //
                .arg(action.source.name)
                .arg(action.state == providers::twitch::ModeChangedAction::State::On ? "on" : "off")
                .arg(action.getModeName());

        if (action.duration > 0) {
            text.append(" (" + QString::number(action.duration) + " seconds)");
        }

        auto msg = messages::Message::createSystemMessage(text);
        util::postToThread([chan, msg] { chan->addMessage(msg); });
    });

    this->twitch.pubsub->sig.moderation.moderationStateChanged.connect([this](const auto &action) {
        auto chan = this->twitch.server->getChannelOrEmptyByID(action.roomID);
        if (chan->isEmpty()) {
            return;
        }

        QString text;

        if (action.modded) {
            text = QString("%1 modded %2").arg(action.source.name, action.target.name);
        } else {
            text = QString("%1 unmodded %2").arg(action.source.name, action.target.name);
        }

        auto msg = messages::Message::createSystemMessage(text);
        util::postToThread([chan, msg] { chan->addMessage(msg); });
    });

    this->twitch.pubsub->sig.moderation.userBanned.connect([&](const auto &action) {
        auto chan = this->twitch.server->getChannelOrEmptyByID(action.roomID);

        if (chan->isEmpty()) {
            return;
        }

        auto msg = messages::Message::createTimeoutMessage(action);
        msg->flags |= messages::Message::PubSub;

        util::postToThread([chan, msg] { chan->addOrReplaceTimeout(msg); });
    });

    this->twitch.pubsub->sig.moderation.userUnbanned.connect([&](const auto &action) {
        auto chan = this->twitch.server->getChannelOrEmptyByID(action.roomID);

        if (chan->isEmpty()) {
            return;
        }

        auto msg = messages::Message::createUntimeoutMessage(action);

        util::postToThread([chan, msg] { chan->addMessage(msg); });
    });

    this->twitch.pubsub->start();

    auto RequestModerationActions = [=]() {
        this->twitch.pubsub->unlistenAllModerationActions();
        // TODO(pajlada): Unlisten to all authed topics instead of only moderation topics
        // this->twitch.pubsub->UnlistenAllAuthedTopics();

        this->twitch.pubsub->listenToWhispers(this->accounts->twitch.getCurrent());  //
    };

    this->accounts->twitch.currentUserChanged.connect(RequestModerationActions);

    RequestModerationActions();
}

int Application::run(QApplication &qtApp)
{
    // Start connecting to the IRC Servers (Twitch only for now)
    this->twitch.server->connect();

    // Show main window
    this->windows->getMainWindow().show();

    return qtApp.exec();
}

void Application::save()
{
    this->windows->save();

    this->commands->save();
}

Application *getApp()
{
    assert(staticApp != nullptr);

    return staticApp;
}

bool appInitialized()
{
    return isAppInitialized;
}

}  // namespace chatterino
<commit_msg>disabled openGuiMessageQueue for debug mode<commit_after>#include "application.hpp"

#include "controllers/accounts/accountcontroller.hpp"
#include "controllers/commands/commandcontroller.hpp"
#include "controllers/highlights/highlightcontroller.hpp"
#include "controllers/ignores/ignorecontroller.hpp"
#include "controllers/taggedusers/taggeduserscontroller.hpp"
#include "providers/twitch/pubsub.hpp"
#include "providers/twitch/twitchserver.hpp"
#include "singletons/emotemanager.hpp"
#include "singletons/fontmanager.hpp"
#include "singletons/loggingmanager.hpp"
#include "singletons/nativemessagingmanager.hpp"
#include "singletons/pathmanager.hpp"
#include "singletons/resourcemanager.hpp"
#include "singletons/settingsmanager.hpp"
#include "singletons/thememanager.hpp"
#include "singletons/windowmanager.hpp"
#include "util/posttothread.hpp"

#include <atomic>

using namespace chatterino::singletons;

namespace chatterino {

namespace {

bool isBigEndian()
{
    int test = 1;
    char *p = reinterpret_cast<char *>(&test);

    return p[0] == 0;
}

}  // namespace

static std::atomic<bool> isAppConstructed{false};
static std::atomic<bool> isAppInitialized{false};

static Application *staticApp = nullptr;

// this class is responsible for handling the workflow of Chatterino
// It will create the instances of the major classes, and connect their signals to each other

Application::Application(int _argc, char **_argv)
    : argc(_argc)
    , argv(_argv)
{
}

void Application::construct()
{
    assert(isAppConstructed == false);
    isAppConstructed = true;

    // 1. Instantiate all classes
    this->settings = new singletons::SettingManager;
    this->paths = singletons::PathManager::getInstance();
    this->themes = new singletons::ThemeManager;
    this->windows = new singletons::WindowManager;
    this->logging = new singletons::LoggingManager;
    this->commands = new controllers::commands::CommandController;
    this->highlights = new controllers::highlights::HighlightController;
    this->ignores = new controllers::ignores::IgnoreController;
    this->taggedUsers = new controllers::taggedusers::TaggedUsersController;
    this->accounts = new controllers::accounts::AccountController;
    this->emotes = new singletons::EmoteManager;
    this->fonts = new singletons::FontManager;
    this->resources = new singletons::ResourceManager;

    this->twitch.server = new providers::twitch::TwitchServer;
    this->twitch.pubsub = new providers::twitch::PubSub;
}

void Application::instantiate(int argc, char **argv)
{
    assert(staticApp == nullptr);

    staticApp = new Application(argc, argv);
}

void Application::initialize()
{
    assert(isAppInitialized == false);
    isAppInitialized = true;

    // 2. Initialize/load classes
    this->settings->initialize();

    this->settings->load();
    this->commands->load();
    this->logging->initialize();
    this->windows->initialize();

    this->resources->initialize();

    this->highlights->initialize();
    this->ignores->initialize();

    this->emotes->initialize();

    this->accounts->load();

    this->twitch.server->initialize();

    // XXX
    this->settings->updateWordTypeMask();

#ifdef Q_OS_WIN
#ifdef QT_DEBUG
#ifdef C_DEBUG_NM
    this->nativeMessaging->registerHost();
    this->nativeMessaging->openGuiMessageQueue();
#endif
#else
    this->nativeMessaging->registerHost();
    this->nativeMessaging->openGuiMessageQueue();
#endif
#endif

    this->twitch.pubsub->sig.whisper.sent.connect([](const auto &msg) {
        debug::Log("WHISPER SENT LOL");  //
    });

    this->twitch.pubsub->sig.whisper.received.connect([](const auto &msg) {
        debug::Log("WHISPER RECEIVED LOL");  //
    });

    this->twitch.pubsub->sig.moderation.chatCleared.connect([this](const auto &action) {
        auto chan = this->twitch.server->getChannelOrEmptyByID(action.roomID);
        if (chan->isEmpty()) {
            return;
        }

        QString text = QString("%1 cleared the chat").arg(action.source.name);

        auto msg = messages::Message::createSystemMessage(text);
        util::postToThread([chan, msg] { chan->addMessage(msg); });
    });

    this->twitch.pubsub->sig.moderation.modeChanged.connect([this](const auto &action) {
        auto chan = this->twitch.server->getChannelOrEmptyByID(action.roomID);
        if (chan->isEmpty()) {
            return;
        }

        QString text =
            QString("%1 turned %2 %3 mode")  //
                .arg(action.source.name)
                .arg(action.state == providers::twitch::ModeChangedAction::State::On ? "on" : "off")
                .arg(action.getModeName());

        if (action.duration > 0) {
            text.append(" (" + QString::number(action.duration) + " seconds)");
        }

        auto msg = messages::Message::createSystemMessage(text);
        util::postToThread([chan, msg] { chan->addMessage(msg); });
    });

    this->twitch.pubsub->sig.moderation.moderationStateChanged.connect([this](const auto &action) {
        auto chan = this->twitch.server->getChannelOrEmptyByID(action.roomID);
        if (chan->isEmpty()) {
            return;
        }

        QString text;

        if (action.modded) {
            text = QString("%1 modded %2").arg(action.source.name, action.target.name);
        } else {
            text = QString("%1 unmodded %2").arg(action.source.name, action.target.name);
        }

        auto msg = messages::Message::createSystemMessage(text);
        util::postToThread([chan, msg] { chan->addMessage(msg); });
    });

    this->twitch.pubsub->sig.moderation.userBanned.connect([&](const auto &action) {
        auto chan = this->twitch.server->getChannelOrEmptyByID(action.roomID);

        if (chan->isEmpty()) {
            return;
        }

        auto msg = messages::Message::createTimeoutMessage(action);
        msg->flags |= messages::Message::PubSub;

        util::postToThread([chan, msg] { chan->addOrReplaceTimeout(msg); });
    });

    this->twitch.pubsub->sig.moderation.userUnbanned.connect([&](const auto &action) {
        auto chan = this->twitch.server->getChannelOrEmptyByID(action.roomID);

        if (chan->isEmpty()) {
            return;
        }

        auto msg = messages::Message::createUntimeoutMessage(action);

        util::postToThread([chan, msg] { chan->addMessage(msg); });
    });

    this->twitch.pubsub->start();

    auto RequestModerationActions = [=]() {
        this->twitch.pubsub->unlistenAllModerationActions();
        // TODO(pajlada): Unlisten to all authed topics instead of only moderation topics
        // this->twitch.pubsub->UnlistenAllAuthedTopics();

        this->twitch.pubsub->listenToWhispers(this->accounts->twitch.getCurrent());  //
    };

    this->accounts->twitch.currentUserChanged.connect(RequestModerationActions);

    RequestModerationActions();
}

int Application::run(QApplication &qtApp)
{
    // Start connecting to the IRC Servers (Twitch only for now)
    this->twitch.server->connect();

    // Show main window
    this->windows->getMainWindow().show();

    return qtApp.exec();
}

void Application::save()
{
    this->windows->save();

    this->commands->save();
}

Application *getApp()
{
    assert(staticApp != nullptr);

    return staticApp;
}

bool appInitialized()
{
    return isAppInitialized;
}

}  // namespace chatterino
<|endoftext|>


<commit_before>//$$CDS-header$$

#include "map2/map_find_string.h"

namespace map2 {
    CPPUNIT_TEST_SUITE_REGISTRATION( Map_find_string );

    void Map_find_string::generateSequence()
    {
        size_t nPercent = c_nPercentExists;

        if ( nPercent > 100 )
            nPercent = 100;
        else if ( nPercent < 1 )
            nPercent = 1;

        std::vector<std::string> const& arrString = CppUnitMini::TestCase::getTestStrings();
        size_t nSize = arrString.size();
        if ( nSize > c_nMapSize )
            nSize = c_nMapSize;
        m_Arr.reserve( nSize );

        nSize = 0;
        for ( size_t i = 0; i < nSize && i < arrString.size(); ++i ) {
        bool bExists = CppUnitMini::Rand( 100 ) <= nPercent;
            m_Arr.push_back( { &arrString.at(i), bExists } );
            if ( bExists )
                ++nSize;
        }
        c_nMapSize = nSize;
    }

    void Map_find_string::setUpParams( const CppUnitMini::TestCfg& cfg )
    {
        c_nThreadCount = cfg.getSizeT("ThreadCount", c_nThreadCount );
        c_nMapSize = cfg.getSizeT("MapSize", c_nMapSize);
        c_nPercentExists = cfg.getSizeT("PercentExists", c_nPercentExists);
        c_nPassCount = cfg.getSizeT("PassCount", c_nPassCount);
        c_nMaxLoadFactor = cfg.getSizeT("MaxLoadFactor", c_nMaxLoadFactor);
        c_bPrintGCState = cfg.getBool("PrintGCStateFlag", c_bPrintGCState );

        c_nCuckooInitialSize = cfg.getSizeT("CuckooInitialSize", c_nCuckooInitialSize);
        c_nCuckooProbesetSize = cfg.getSizeT("CuckooProbesetSize", c_nCuckooProbesetSize);
        c_nCuckooProbesetThreshold = cfg.getSizeT("CuckooProbesetThreshold", c_nCuckooProbesetThreshold);

        c_nFeldmanMap_HeadBits = cfg.getSizeT("FeldmanMapHeadBits", c_nFeldmanMap_HeadBits);
        c_nFeldmanMap_ArrayBits = cfg.getSizeT("FeldmanMapArrayBits", c_nFeldmanMap_ArrayBits);

        if ( c_nThreadCount == 0 )
            c_nThreadCount = std::thread::hardware_concurrency();

        CPPUNIT_MSG( "Generating test data...\n");
        cds::OS::Timer    timer;
        generateSequence();
        CPPUNIT_MSG( "   Duration=" << timer.duration() << "\n" );

    }
} // namespace map2
<commit_msg>formatting<commit_after>//$$CDS-header$$

#include "map2/map_find_string.h"

namespace map2 {
    CPPUNIT_TEST_SUITE_REGISTRATION( Map_find_string );

    void Map_find_string::generateSequence()
    {
        size_t nPercent = c_nPercentExists;

        if ( nPercent > 100 )
            nPercent = 100;
        else if ( nPercent < 1 )
            nPercent = 1;

        std::vector<std::string> const& arrString = CppUnitMini::TestCase::getTestStrings();
        size_t nSize = arrString.size();
        if ( nSize > c_nMapSize )
            nSize = c_nMapSize;
        m_Arr.reserve( nSize );

        nSize = 0;
        for ( size_t i = 0; i < nSize && i < arrString.size(); ++i ) {
            bool bExists = CppUnitMini::Rand( 100 ) <= nPercent;
            m_Arr.push_back( { &arrString.at(i), bExists } );
            if ( bExists )
                ++nSize;
        }
        c_nMapSize = nSize;
    }

    void Map_find_string::setUpParams( const CppUnitMini::TestCfg& cfg )
    {
        c_nThreadCount = cfg.getSizeT("ThreadCount", c_nThreadCount );
        c_nMapSize = cfg.getSizeT("MapSize", c_nMapSize);
        c_nPercentExists = cfg.getSizeT("PercentExists", c_nPercentExists);
        c_nPassCount = cfg.getSizeT("PassCount", c_nPassCount);
        c_nMaxLoadFactor = cfg.getSizeT("MaxLoadFactor", c_nMaxLoadFactor);
        c_bPrintGCState = cfg.getBool("PrintGCStateFlag", c_bPrintGCState );

        c_nCuckooInitialSize = cfg.getSizeT("CuckooInitialSize", c_nCuckooInitialSize);
        c_nCuckooProbesetSize = cfg.getSizeT("CuckooProbesetSize", c_nCuckooProbesetSize);
        c_nCuckooProbesetThreshold = cfg.getSizeT("CuckooProbesetThreshold", c_nCuckooProbesetThreshold);

        c_nFeldmanMap_HeadBits = cfg.getSizeT("FeldmanMapHeadBits", c_nFeldmanMap_HeadBits);
        c_nFeldmanMap_ArrayBits = cfg.getSizeT("FeldmanMapArrayBits", c_nFeldmanMap_ArrayBits);

        if ( c_nThreadCount == 0 )
            c_nThreadCount = std::thread::hardware_concurrency();

        CPPUNIT_MSG( "Generating test data...\n");
        cds::OS::Timer    timer;
        generateSequence();
        CPPUNIT_MSG( "   Duration=" << timer.duration() << "\n" );

    }
} // namespace map2
<|endoftext|>


<commit_before>#define CATCH_CONFIG_RUNNER
#include <catch.hpp>
#include "sphere.cpp"
#include "box.hpp"
#include "color.hpp"
#include <glm/vec3.hpp>
#include <string>
#include <glm/glm.hpp>
#include <glm/gtx/intersect.hpp>

TEST_CASE("get volume of sphere", "[volume]") {
	Sphere sphere;
	REQUIRE(sphere.volume() == Approx(4.1888));
}

TEST_CASE("get area of sphere", "[area]") {
	Sphere sphere;
	REQUIRE(sphere.area() == Approx(12.5664));
}

TEST_CASE("get radius of sphere", "[radius]") {
	Sphere sphere;
	REQUIRE(sphere.radius() == 1);
}

TEST_CASE("get center of sphere", "[center]") {
	Sphere sphere;
	glm::vec3 tmp{0,0,0};
	REQUIRE(sphere.center() == tmp);
}

TEST_CASE("constructors of sphere", "[constructors]") {
	Sphere s1;
	Sphere s2{{0,0,0},1};
	REQUIRE(s1.center() == s2.center());
	REQUIRE(s1.radius() == s2.radius());
	REQUIRE(s1.area() == s2.area());
	REQUIRE(s1.volume() == s2.volume());
}

TEST_CASE("constructors for box", "[constructors]") {
	Box b1;
	glm::vec3 tmp{0,0,0};
	REQUIRE(b1.min() == tmp);
	tmp = {1,1,1};
	REQUIRE(b1.max() == tmp);
	Box b2{{1,1,3},{3,2,2}};
	tmp = {1,1,2};
	REQUIRE(b2.min() == tmp);
	tmp = {3,2,3};
	REQUIRE(b2.max() == tmp);
}

TEST_CASE("get area of box", "[area]") {
	Box box;
	REQUIRE(box.area() == 6);
}

TEST_CASE("get volume of box", "[area]") {
	Box box;
	REQUIRE(box.volume() == 1);
}

TEST_CASE("get color of sphere", "[color]") {
	Sphere sphere;
	Color tmp{100,100,100};
	REQUIRE(sphere.color().r == tmp.r);
	REQUIRE(sphere.color().g == tmp.g);
	REQUIRE(sphere.color().b == tmp.b);
}

TEST_CASE("get name of sphere", "[name]") {
	Sphere sphere;
	REQUIRE(sphere.name() == "default");
}

TEST_CASE("shape constructor for sphere") {
	Sphere sphere{"test",{1,2,3},4.2,{255,200,200}};
	REQUIRE(sphere.name() == "test");
	REQUIRE(sphere.color().r == 255);
	glm::vec3 tmp{1,2,3};
	REQUIRE(sphere.center() == tmp);
	REQUIRE(sphere.radius() == 4.2);
}

TEST_CASE("get color of box", "[color]") {
	Box box;
	Color tmp{100,100,100};
	REQUIRE(box.color().r == tmp.r);
	REQUIRE(box.color().g == tmp.g);
	REQUIRE(box.color().b == tmp.b);
}

TEST_CASE("get name of box", "[name]") {
	Box box;
	REQUIRE(box.name() == "default");
}

TEST_CASE("shape constructor for box") {
	Box box{"test",{1,2,3},{4,5,6},{255,200,200}};
	REQUIRE(box.name() == "test");
	REQUIRE(box.color().r == 255);
	glm::vec3 tmp{1,2,3};
	REQUIRE(box.min() == tmp);
	tmp = {4,5,6};
	REQUIRE(box.max() == tmp);
}

TEST_CASE("use ostream of shape", "[ostream]") {
	Sphere sphere;
	std::cout << sphere << std::endl;
}

TEST_CASE("use ostream of box", "[ostream]") {
	Box box;
	std::cout << box << std::endl;
}

int main(int argc, char *argv[]) {
  return Catch::Session().run(argc, argv);
}
<commit_msg>Add comment for 6.7<commit_after>#define CATCH_CONFIG_RUNNER
#include <catch.hpp>
#include "sphere.cpp"
#include "box.hpp"
#include "color.hpp"
#include <glm/vec3.hpp>
#include <string>
#include <glm/glm.hpp>
#include <glm/gtx/intersect.hpp>

TEST_CASE("get volume of sphere", "[volume]") {
	Sphere sphere;
	REQUIRE(sphere.volume() == Approx(4.1888));
}

TEST_CASE("get area of sphere", "[area]") {
	Sphere sphere;
	REQUIRE(sphere.area() == Approx(12.5664));
}

TEST_CASE("get radius of sphere", "[radius]") {
	Sphere sphere;
	REQUIRE(sphere.radius() == 1);
}

TEST_CASE("get center of sphere", "[center]") {
	Sphere sphere;
	glm::vec3 tmp{0,0,0};
	REQUIRE(sphere.center() == tmp);
}

TEST_CASE("constructors of sphere", "[constructors]") {
	Sphere s1;
	Sphere s2{{0,0,0},1};
	REQUIRE(s1.center() == s2.center());
	REQUIRE(s1.radius() == s2.radius());
	REQUIRE(s1.area() == s2.area());
	REQUIRE(s1.volume() == s2.volume());
}

TEST_CASE("constructors for box", "[constructors]") {
	Box b1;
	glm::vec3 tmp{0,0,0};
	REQUIRE(b1.min() == tmp);
	tmp = {1,1,1};
	REQUIRE(b1.max() == tmp);
	Box b2{{1,1,3},{3,2,2}};
	tmp = {1,1,2};
	REQUIRE(b2.min() == tmp);
	tmp = {3,2,3};
	REQUIRE(b2.max() == tmp);
}

TEST_CASE("get area of box", "[area]") {
	Box box;
	REQUIRE(box.area() == 6);
}

TEST_CASE("get volume of box", "[area]") {
	Box box;
	REQUIRE(box.volume() == 1);
}

TEST_CASE("get color of sphere", "[color]") {
	Sphere sphere;
	Color tmp{100,100,100};
	REQUIRE(sphere.color().r == tmp.r);
	REQUIRE(sphere.color().g == tmp.g);
	REQUIRE(sphere.color().b == tmp.b);
}

TEST_CASE("get name of sphere", "[name]") {
	Sphere sphere;
	REQUIRE(sphere.name() == "default");
}

TEST_CASE("shape constructor for sphere") {
	Sphere sphere{{1,2,3},4.2,{255,200,200},"test"};
	REQUIRE(sphere.name() == "test");
	REQUIRE(sphere.color().r == 255);
	glm::vec3 tmp{1,2,3};
	REQUIRE(sphere.center() == tmp);
	REQUIRE(sphere.radius() == 4.2);
}

TEST_CASE("get color of box", "[color]") {
	Box box;
	Color tmp{100,100,100};
	REQUIRE(box.color().r == tmp.r);
	REQUIRE(box.color().g == tmp.g);
	REQUIRE(box.color().b == tmp.b);
}

TEST_CASE("get name of box", "[name]") {
	Box box;
	REQUIRE(box.name() == "default");
}

TEST_CASE("shape constructor for box") {
	Box box{{1,2,3},{4,5,6},{255,200,200},"test"};
	REQUIRE(box.name() == "test");
	REQUIRE(box.color().r == 255);
	glm::vec3 tmp{1,2,3};
	REQUIRE(box.min() == tmp);
	tmp = {4,5,6};
	REQUIRE(box.max() == tmp);
}

TEST_CASE("use ostream of shape", "[ostream]") {
	Sphere sphere;
	std::cout << sphere << std::endl;
}

TEST_CASE("use ostream of box", "[ostream]") {
	Box box;
	std::cout << box << std::endl;
}

TEST_CASE("intersectRaySphere", "[intersect]") {
	//Ray
	glm :: vec3 ray_origin (0.0 ,0.0 ,0.0);
	//ray direction has to be normalized!
	//you can use:
	//v = glm::normalize(some_vector)
	glm::vec3 ray_direction(0.0,0.0,1.0);
	// Sphere
	glm::vec3 sphere_center(0.0,0.0,5.0);
	float sphere_radius(1.0);

	float distance (0.0);
	auto result = glm::intersectRaySphere(
	ray_origin, ray_direction,
	sphere_center, sphere_radius,
	distance);
	REQUIRE(distance == Approx(4.0f));
}

TEST_CASE("intersect ray with sphere method","[intersect]") {
	Ray ray{{0.0f,0.0f,0.0f},{0.0,0.0,1.0}};
	Sphere sphere{{0.0,0.0,5.0},1.0};
	float distance{0.0};
	REQUIRE(sphere.intersect(ray,distance) == true);
	REQUIRE(distance == Approx(4.0f));
}

int main(int argc, char *argv[]) {
  return Catch::Session().run(argc, argv);
}

/* Aufgabe 6.7
	s1 ist ein shared Pointer vom Typ sphere.
	s2 ist ein shared pointer vom Typ shape.
	s1 ist hier statisch,
	da ihm nur Objekte des Typs sphere zugewiesen werden koennen.
	s2 dagegen ist dynamisch, weil es sich um einen Typ der Basisklasse handelt:
	Es kann ihr sowohl ein Objekt vom Typ der Basisklasse,
	als auch eines der abgeleiteten Klasse zugewiesen werden.

	Falls sphere noch eine abgeleitete Klasse haette,
	so wuerde s1 auch insofern dynamisch sein,
	als dass man ein Objekt der abgeleiteten Klasse zuweisen kann.
*/<|endoftext|>


<commit_before>#include <vector>
#include <cmath>
#include <iostream>

using namespace std;

vector<double> imageToGround(double sample, double line, double height);
vector<double> intersect(const vector<double> &point,
                         const vector<double> &direction,
                         double radius);
vector<double> perpendicular(const vector<double> &v1, const vector<double> &v2);
vector<double> project(const vector<double> &v1, const vector<double> &v2);
double dot(const vector<double> &v1, const vector<double> &v2);
double magnitude(const vector<double> &v);
vector<double> normalize(const vector<double> &v);

int main() {

  vector<double> i2g = imageToGround(500, 500, 1000);
  cout << i2g[0] << endl;
  cout << i2g[1] << endl;
  cout << i2g[2] << endl;

  return 0;
}

vector<double> imageToGround(double sample, double line, double height) {
  double focalLength = 549.302734762479;

  vector<double> spacecraftPosition(3);

  spacecraftPosition[0] = -6683432.694790688; // SENSOR X
  spacecraftPosition[1] = -27264735.61516516; // SENSOR Y
  spacecraftPosition[2] = 8536481.287414147; // SENSOR Z from isd

  const double transX[3] = {0.0, 0.014, 0.0};
  const double transY[3] = {0.0, 0.0, 0.014};

  // center the sample line
  // imgSamps / 2, imgLines / 2: 1024x1024
  sample -= 512.0; // ISD needs a center sample in CSM coord
  line -= 512.0; // ISD needs a center line in CSM coord (.5 .5 pixel centers)

  double focalPlaneX = transX[0] + (transX[1] * sample) + (transX[2] * line);
  double focalPlaneY = transY[0] + (transY[1] * sample) + (transY[2] * line);
  cout << "Focal plane x: " << focalPlaneX << endl;
  cout << "Focal plane y: " << focalPlaneY << endl;

  double majorAxis = 6051800; // mercury ellipsoid

  vector<double> direction(3);

  direction[0] = focalPlaneX / 1000 - spacecraftPosition[0];
  direction[1] = focalPlaneY / 1000 - spacecraftPosition[1];
  direction[2] = focalLength / 1000 - spacecraftPosition[2];

  cout << "Direction: " << endl;
  cout << direction[0] << endl;
  cout << direction[1] << endl;
  cout << direction[2] << endl;
  cout << endl;

  intersect(spacecraftPosition, direction, majorAxis);
}

vector<double> intersect(const vector<double> &point,
                         const vector<double> &direction,
                         double radius) {

  vector<double> intersectionPoint(3);
  vector<double> newPoint(3), newDirection(3);

  newDirection[0] = direction[0] / radius;
  newDirection[1] = direction[1] / radius;
  newDirection[2] = direction[2] / radius;

  cout << "New Direction: " << endl;
  cout << newDirection[0] << endl;
  cout << newDirection[1] << endl;
  cout << newDirection[2] << endl;
  cout << endl;

  newPoint[0] = point[0] / radius;
  newPoint[1] = point[1] / radius;
  newPoint[2] = point[2] / radius;

  cout << "New Point: " << endl;
  cout << newPoint[0] << endl;
  cout << newPoint[1] << endl;
  cout << newPoint[2] << endl;
  cout << endl;

  vector<double> perpendicularV = perpendicular(newPoint, newDirection);

  vector<double> newPointProj(3);
  newPointProj[0] = newPoint[0] - perpendicularV[0];
  newPointProj[1] = newPoint[1] - perpendicularV[1];
  newPointProj[2] = newPoint[2] - perpendicularV[2];

  double newPointMag = magnitude(newPoint);
  double perpendicularMag = magnitude(perpendicularV);

  vector<double> newDirectionNorm = normalize(newDirection);

  int sign = 1;
  if (newPointMag > 1.0) {
    if (perpendicularMag > 1.0) {
      return intersectionPoint; // empty
    }

    if (dot(newPointProj, newDirection) > 0.0) {
      return intersectionPoint; // empty
    }

    if (perpendicularMag == 1.0) {
      intersectionPoint[0] = perpendicularV[0] * radius;
      intersectionPoint[1] = perpendicularV[1] * radius;
      intersectionPoint[2] = perpendicularV[2] * radius;
      return intersectionPoint;
    }

    sign = -1;
  }
  else if (newPointMag == 1.0) {
    return point;
  }
  else {
    sign = 1;
  }

  double scale = 1 - perpendicularMag * perpendicularMag;
  if (scale < 0.0) {
    scale = 0.0;
  }
  scale = sqrt(scale);

  intersectionPoint[0] = perpendicularV[0] + sign * scale * newDirectionNorm[0];
  intersectionPoint[1] = perpendicularV[1] + sign * scale * newDirectionNorm[1];
  intersectionPoint[2] = perpendicularV[2] + sign * scale * newDirectionNorm[2];

  return intersectionPoint;
}

vector<double> perpendicular(const vector<double> &v1, const vector<double> &v2) {

  double max1 = 0;
  double max2 = 0;

  for (int i = 0; i < 3; i++) {
    if (abs(v1[i]) > max1) {
      max1 = abs(v1[i]);
    }
    if (abs(v2[i]) > max2) {
      max2 = abs(v2[i]);
    }
  }

  vector<double> newV1(3), newV2(3);

  newV1[0] = v1[0]/max1;
  newV1[1] = v1[1]/max1;
  newV1[2] = v1[2]/max1;

  newV2[0] = v2[0]/max2;
  newV2[1] = v2[1]/max2;
  newV2[2] = v2[2]/max2;

  vector<double> parallelV = project(newV1, newV2);

  vector<double> perpendicularV (3);

  perpendicularV[0] = v1[0] - parallelV[0] * max1;
  perpendicularV[1] = v1[1] - parallelV[1] * max1;
  perpendicularV[2] = v1[2] - parallelV[2] * max1;

  return perpendicularV;
}

vector<double> project(const vector<double> &v1, const vector<double> &v2) {
  double v1Dotv2 = dot(v1, v2);
  double v2Dotv2 = dot(v2, v2);
  vector<double> projV (3);
  projV[0] = v1Dotv2/v2Dotv2 * v2[0];
  projV[1] = v1Dotv2/v2Dotv2 * v2[1];
  projV[2] = v1Dotv2/v2Dotv2 * v2[2];
  return projV;
}

double dot(const vector<double> &v1, const vector<double> &v2) {
  return v1[0] * v2[0] + v1[1] * v2[1] + v1[2] * v2[2];
}

double magnitude(const vector<double> &v) {
  return sqrt(v[0] * v[0] + v[1] * v[1] + v[2] * v[2]);
}

vector<double> normalize(const vector<double> &v) {
  double magnitude;
  magnitude = sqrt(v[0] * v[0] + v[1] * v[1] + v[2] * v[2]);
  vector<double> n (3);
  n[0] = v[0] / magnitude;
  n[1] = v[1] / magnitude;
  n[2] = v[2] / magnitude;
  return n;
}

<commit_msg>Added thorough commentary.<commit_after>#include <vector>
#include <cmath>
#include <iostream>

using namespace std;

vector<double> imageToGround(double sample, double line, double height);
vector<double> intersect(const vector<double> &point,
                         const vector<double> &direction,
                         double radius);
vector<double> perpendicular(const vector<double> &v1, const vector<double> &v2);
vector<double> project(const vector<double> &v1, const vector<double> &v2);
double dot(const vector<double> &v1, const vector<double> &v2);
double magnitude(const vector<double> &v);
vector<double> normalize(const vector<double> &v);

int main() {

  vector<double> i2g = imageToGround(500, 500, 1000);
  cout << i2g[0] << endl;
  cout << i2g[1] << endl;
  cout << i2g[2] << endl;

  return 0;
}

/**
 * This function determines if a sample, line intersects the target body and if so, where
 * this intersection occurs in body-fixed coordinates.
 *
 * @param sample Sample of the input image.
 * @param line Line of the input image.
 * @param height ???
 *
 * @return @b vector<double> Returns the body-fixed X,Y,Z coordinates of the intersection.
 *                           If no intersection, returns a 3-element vector of 0's.
 */
vector<double> imageToGround(double sample, double line, double height) {
  double focalLength = 549.302734762479; // Will be grabbed from ISD.

  vector<double> spacecraftPosition(3);

  spacecraftPosition[0] = -6683432.694790688; // SENSOR X
  spacecraftPosition[1] = -27264735.61516516; // SENSOR Y
  spacecraftPosition[2] = 8536481.287414147; // SENSOR Z from isd

  const double transX[3] = {0.0, 0.014, 0.0}; // Grabbed from ISD.
  const double transY[3] = {0.0, 0.0, 0.014};

  // center the sample line
  // imgSamps / 2, imgLines / 2: THIS ASSUMES 1024x1024 image with no offsets
  sample -= 512.0; // ISD needs a center sample in CSM coord
  line -= 512.0; // ISD needs a center line in CSM coord (.5 .5 pixel centers)

  // Convert from sample/line to focal plane coordinates
  double focalPlaneX = transX[0] + (transX[1] * sample) + (transX[2] * line);
  double focalPlaneY = transY[0] + (transY[1] * sample) + (transY[2] * line);
  cout << "Focal plane x: " << focalPlaneX << endl;
  cout << "Focal plane y: " << focalPlaneY << endl;

  double majorAxis = 6051800; // mercury ellipsoid (ISD).

  // Determine the look direction of the camera in body-fixed coordinate system
  vector<double> direction(3);

  direction[0] = focalPlaneX / 1000 - spacecraftPosition[0];
  direction[1] = focalPlaneY / 1000 - spacecraftPosition[1];
  direction[2] = focalLength / 1000 - spacecraftPosition[2];

  cout << "Direction: " << endl;
  cout << direction[0] << endl;
  cout << direction[1] << endl;
  cout << direction[2] << endl;
  cout << endl;

  // Try to intersect.
  intersect(spacecraftPosition, direction, majorAxis);
}

/**
 * Given a spacecraft position in body-fixed coordinates, determine if the look direction vector
 * intersects the surface of the target body.
 *
 * @param point 3-element vector representing the spacecraft's position in body-fixed.
 * @param direction 3-element vector representing the camera's look direction in body-fixed.
 * @param radius Radius for the spherical body.
 *
 * @return @b vector<double> Returns a 3-element vector representing the intersection in body-fixed.
 *                           If no intersection, the vector will contain 0's.
 *
 * This code is adapted from the sensorModelRefactor branch's Geometry3D::intersect() method.
 */
vector<double> intersect(const vector<double> &point,
                         const vector<double> &direction,
                         double radius) {

  vector<double> intersectionPoint(3);
  vector<double> newPoint(3), newDirection(3);

  // Transform the look direction vector into unit sphere space.
  newDirection[0] = direction[0] / radius;
  newDirection[1] = direction[1] / radius;
  newDirection[2] = direction[2] / radius;

  cout << "New Direction: " << endl;
  cout << newDirection[0] << endl;
  cout << newDirection[1] << endl;
  cout << newDirection[2] << endl;
  cout << endl;

  // Transform the spacecraft position vector into unit sphere space.
  newPoint[0] = point[0] / radius;
  newPoint[1] = point[1] / radius;
  newPoint[2] = point[2] / radius;

  cout << "New Point: " << endl;
  cout << newPoint[0] << endl;
  cout << newPoint[1] << endl;
  cout << newPoint[2] << endl;
  cout << endl;

  // Find this vector:
  // If you extend the look direction infinitely, find the vector that is
  // perpendicular to that look direction and points to the body's origin.
  vector<double> perpendicularV = perpendicular(newPoint, newDirection);

  // The look direction vector extended to the perpendicular vector.
  vector<double> newPointProj(3);
  newPointProj[0] = newPoint[0] - perpendicularV[0];
  newPointProj[1] = newPoint[1] - perpendicularV[1];
  newPointProj[2] = newPoint[2] - perpendicularV[2];

  // Find magnitudes of the "unit" spacecraft position vector and perpendicular vector.
  double newPointMag = magnitude(newPoint);
  double perpendicularMag = magnitude(perpendicularV);

  // Use max-norm (infinity-norm) to normalize the "unit" look direction vector.
  vector<double> newDirectionNorm = normalize(newDirection);

  // Positive sign indicates spacecraft is in the target body,
  // negative indicates spacecraft is outside the target body.
  int sign = 1;

  // If the spacecraft position is outside the target body
  if (newPointMag > 1.0) {
    // If vector perpendicular to look direction has magnitude > 1,
    // we are not looking at the target body (since the body is a "unit sphere")
    if (perpendicularMag > 1.0) {
      return intersectionPoint; // empty
    }

    // If looking away from the target body, there is no intersection.
    if (dot(newPointProj, newDirection) > 0.0) {
      return intersectionPoint; // empty
    }

    // If intersection point is on the limb, then transform back to target body size.
    if (perpendicularMag == 1.0) {
      intersectionPoint[0] = perpendicularV[0] * radius;
      intersectionPoint[1] = perpendicularV[1] * radius;
      intersectionPoint[2] = perpendicularV[2] * radius;
      return intersectionPoint;
    }

    sign = -1;
  }
  // If the spacecraft is on the target body
  else if (newPointMag == 1.0) {
    return point;
  }
  // If the spacecraft is inside the target body??? (target is sky?)
  else {
    sign = 1;
  }

  // To visualize:
  // There exists a scalar, scale, such that
  // ||perpendicularV||^2 + scale^2 = radius^2.
  // Since we are in unit sphere space, the radius = 1.
  double scale = 1 - perpendicularMag * perpendicularMag;
  if (scale < 0.0) {
    scale = 0.0;
  }
  scale = sqrt(scale);

  // Find the intersection:
  /*
   *              perpendicularV
   * intersect o<-----^
   *          r \     |  scale * normalized look direction * sign
   *           a \    |
   *            d \   |
   *             i \  |
   *              u \ ^
   *               s \|  normalized look direction * sign
   *                  o  center of target body
   */
  // We can multiply the scale by the unit look vector and add the perpendicular vector
  // to get the intersection point
  intersectionPoint[0] = perpendicularV[0] + sign * scale * newDirectionNorm[0];
  intersectionPoint[1] = perpendicularV[1] + sign * scale * newDirectionNorm[1];
  intersectionPoint[2] = perpendicularV[2] + sign * scale * newDirectionNorm[2];

  return intersectionPoint;
}

/**
 * Projects the first vector onto the second vector, then finds the vector that is
 * perpendicular to the projected vector.
 *
 * This function is adapted from the sensorModelRefactor branch's
 * LinearAlgebra::perpendicular() method (which is adapted from naif's vperp).
 *
 * @param v1 Vector to project.
 * @param v2 Vector to project on to.
 *
 * @return @b vector<double> Returns a vector perpendicular to the first vector
 *                           projected on the second vector.
 */
vector<double> perpendicular(const vector<double> &v1, const vector<double> &v2) {

  double max1 = 0;
  double max2 = 0;

  // Get the infinite norm for each vector.
  for (int i = 0; i < 3; i++) {
    if (abs(v1[i]) > max1) {
      max1 = abs(v1[i]);
    }
    if (abs(v2[i]) > max2) {
      max2 = abs(v2[i]);
    }
  }

  // Scale the vectors by their max norms (not sure why this is needed, optimization maybe?).
  vector<double> newV1(3), newV2(3);

  newV1[0] = v1[0] / max1;
  newV1[1] = v1[1] / max1;
  newV1[2] = v1[2] / max1;

  newV2[0] = v2[0] / max2;
  newV2[1] = v2[1] / max2;
  newV2[2] = v2[2] / max2;

  // Project first vector onto second vector.
  vector<double> parallelV = project(newV1, newV2);

  vector<double> perpendicularV(3);

  // Get the perpendicular vector by subtracting the first vector by its projection
  // onto the second.
  perpendicularV[0] = v1[0] - parallelV[0] * max1;
  perpendicularV[1] = v1[1] - parallelV[1] * max1;
  perpendicularV[2] = v1[2] - parallelV[2] * max1;

  return perpendicularV;
}

/**
 * Determines the projection of the first vector onto the second vector.
 *
 * @param v1 First vector to project.
 * @param v2 Second vector that first vector is being projected onto.
 *
 * @return @b vector<double> Returns the first vector projected onto the second.
 */
vector<double> project(const vector<double> &v1, const vector<double> &v2) {
  double v1Dotv2 = dot(v1, v2);
  double v2Dotv2 = dot(v2, v2);
  vector<double> projV(3);
  projV[0] = v1Dotv2 / v2Dotv2 * v2[0];
  projV[1] = v1Dotv2 / v2Dotv2 * v2[1];
  projV[2] = v1Dotv2 / v2Dotv2 * v2[2];
  return projV;
}

/**
 * Returns the dot product of two vectors.
 */
double dot(const vector<double> &v1, const vector<double> &v2) {
  return v1[0] * v2[0] + v1[1] * v2[1] + v1[2] * v2[2];
}

/**
 * Returns the magnitude of a vector.
 */
double magnitude(const vector<double> &v) {
  return sqrt(v[0] * v[0] + v[1] * v[1] + v[2] * v[2]);
}

/**
 * Normalizes the vector (e.g. returns a unit vector).
 */
vector<double> normalize(const vector<double> &v) {
  double magnitude;
  magnitude = sqrt(v[0] * v[0] + v[1] * v[1] + v[2] * v[2]);
  vector<double> n (3);
  n[0] = v[0] / magnitude;
  n[1] = v[1] / magnitude;
  n[2] = v[2] / magnitude;
  return n;
}

<|endoftext|>


<commit_before>/******************************************************************************

  nomlib - C++11 cross-platform game engine

Copyright (c) 2013, Jeffrey Carpenter <i8degrees@gmail.com>
All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:

1. Redistributions of source code must retain the above copyright notice, this
   list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
   this list of conditions and the following disclaimer in the documentation
   and/or other materials provided with the distribution.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

******************************************************************************/
#include <iostream>
#include <cstdlib>
#include <cassert>

#include <nomlib/math.hpp>

/// nom::Color Unit Test 1
nom::int32 do_color_test1 ( void );

/// nom::Color Unit Test 2
nom::int32 do_color_test2 ( void );

/// nom::Color Unit Test 3
nom::int32 do_color_test3 ( void );

/// nom::Color Unit Test 4
nom::int32 do_color_test4 ( void );

/// nom::Coords Unit Test 1
nom::int32 do_coords_test1 ( void );

/// nom::Coords Unit Test 2
nom::int32 do_coords_test2 ( void );

/// nom::Coords Unit Test 3
nom::int32 do_coords_test3 ( void );

/// nom::Coords Unit Test 4
nom::int32 do_coords_test4 ( void );

nom::int32 do_color_test1 ( void )
{
  nom::Color4u testme1 ( 242, 1, 1, 255 );
  nom::Color4u testme2 = NOM_COLOR4U_BLACK;

  if ( testme2 == testme1 ) return NOM_EXIT_FAILURE;

  return NOM_EXIT_SUCCESS;
}

nom::int32 do_color_test2 ( void ) { return NOM_EXIT_SUCCESS; }
nom::int32 do_color_test3 ( void ) { return NOM_EXIT_SUCCESS; }
nom::int32 do_color_test4 ( void ) { return NOM_EXIT_SUCCESS; }

nom::int32 do_coords_test1 ( void )
{
  nom::Coords testme1 ( 242, 1, 1, 0 );
  nom::Coords testme2 ( -1, -1, -1, -1 );

  if ( testme1.isNull() ) return NOM_EXIT_FAILURE;
  if ( testme2.isNull() ) return NOM_EXIT_SUCCESS;
  if ( testme2 == nom::Coords::null ) return NOM_EXIT_SUCCESS;

  testme1 = testme2;

  if ( testme1.isNull() ) return NOM_EXIT_SUCCESS;
  if ( testme2.isNull() ) return NOM_EXIT_SUCCESS;
  if ( testme2 == nom::Coords::null ) return NOM_EXIT_SUCCESS;

  return NOM_EXIT_SUCCESS;
}

nom::int32 do_coords_test2 ( void ) { return NOM_EXIT_SUCCESS; }
nom::int32 do_coords_test3 ( void ) { return NOM_EXIT_SUCCESS; }
nom::int32 do_coords_test4 ( void ) { return NOM_EXIT_SUCCESS; }

nom::int32 main ( nom::int32 args_count, char* args[] )
{
  if ( do_color_test1() != NOM_EXIT_SUCCESS )
  {
    NOM_LOG_ERR ( NOM_UNIT_TEST, "Failed nom::Color unit test 1" );
    return NOM_EXIT_FAILURE;
  }

  if ( do_color_test2() != NOM_EXIT_SUCCESS )
  {
    NOM_LOG_ERR ( NOM_UNIT_TEST, "Failed nom::Color unit test 2" );
    return NOM_EXIT_FAILURE;
  }

  if ( do_color_test3() != NOM_EXIT_SUCCESS )
  {
    NOM_LOG_ERR ( NOM_UNIT_TEST, "Failed nom::Color unit test 3" );
    return NOM_EXIT_FAILURE;
  }

  if ( do_color_test4() != NOM_EXIT_SUCCESS )
  {
    NOM_LOG_ERR ( NOM_UNIT_TEST, "Failed nom::Color unit test 4" );
    return NOM_EXIT_FAILURE;
  }

  if ( do_coords_test1() != NOM_EXIT_SUCCESS )
  {
    NOM_LOG_ERR ( NOM_UNIT_TEST, "Failed nom::Coords unit test 1" );
    return NOM_EXIT_FAILURE;
  }

  if ( do_coords_test2() != NOM_EXIT_SUCCESS )
  {
    NOM_LOG_ERR ( NOM_UNIT_TEST, "Failed nom::Coords unit test 2" );
    return NOM_EXIT_FAILURE;
  }

  if ( do_coords_test3() != NOM_EXIT_SUCCESS )
  {
    NOM_LOG_ERR ( NOM_UNIT_TEST, "Failed nom::Coords unit test 3" );
    return NOM_EXIT_FAILURE;
  }

  if ( do_coords_test4() != NOM_EXIT_SUCCESS )
  {
    NOM_LOG_ERR ( NOM_UNIT_TEST, "Failed nom::Coords unit test 4" );
    return NOM_EXIT_FAILURE;
  }

  NOM_LOG_INFO ( NOM_UNIT_TEST, "Math Unit Tests: Pass!" );
  return NOM_EXIT_SUCCESS;
}
<commit_msg>tests/math.cpp: Implement a few tests for Point2, Rect & Color4::null<commit_after>/******************************************************************************

  nomlib - C++11 cross-platform game engine

Copyright (c) 2013, Jeffrey Carpenter <i8degrees@gmail.com>
All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:

1. Redistributions of source code must retain the above copyright notice, this
   list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
   this list of conditions and the following disclaimer in the documentation
   and/or other materials provided with the distribution.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

******************************************************************************/
#include <iostream>
#include <cstdlib>
#include <cassert>

#include <nomlib/math.hpp>

using namespace nom;

/// nom::Color Unit Test 1
nom::int32 do_color_test1 ( void );

/// nom::Color Unit Test 2
nom::int32 do_color_test2 ( void );

/// nom::Color Unit Test 3
nom::int32 do_color_test3 ( void );

/// nom::Color Unit Test 4
nom::int32 do_color_test4 ( void );

/// nom::Coords Unit Test 1
nom::int32 do_coords_test1 ( void );

/// nom::Coords Unit Test 2
nom::int32 do_coords_test2 ( void );

/// nom::Coords Unit Test 3
nom::int32 do_coords_test3 ( void );

/// nom::Coords Unit Test 4
nom::int32 do_coords_test4 ( void );

nom::int32 do_color_test1 ( void )
{
  NOM_LOG_TRACE(NOM);

  nom::Color4u testme1 ( 242, 1, 1, 255 );
  nom::Color4u testme2 = nom::Color4u::Black;
  nom::Color4u testme3 (-1,-1,-1, Color4u::ALPHA_OPAQUE );
  nom::Color4f testme4 (-1,-1,-1, Color4f::ALPHA_OPAQUE );

  NOM_DUMP_VAR(testme1);
  NOM_DUMP_VAR(testme2);
  NOM_DUMP_VAR(testme3);
  NOM_DUMP_VAR(testme4);

  if ( testme2 == testme1 ) return NOM_EXIT_FAILURE;
  if ( testme3 != Color4u::null ) return NOM_EXIT_FAILURE;
  if ( testme4 != Color4f::null ) return NOM_EXIT_FAILURE;

  return NOM_EXIT_SUCCESS;
}

nom::int32 do_color_test2 ( void ) { return NOM_EXIT_SUCCESS; }
nom::int32 do_color_test3 ( void ) { return NOM_EXIT_SUCCESS; }
nom::int32 do_color_test4 ( void ) { return NOM_EXIT_SUCCESS; }

nom::int32 do_coords_test1 ( void )
{
  nom::Coords testme1 ( 242, 1, 1, 0 );
  nom::Coords testme2 ( -1, -1, -1, -1 );

  if ( testme1.isNull() ) return NOM_EXIT_FAILURE;
  if ( testme2.isNull() ) return NOM_EXIT_SUCCESS;
  if ( testme2 == nom::Coords::null ) return NOM_EXIT_SUCCESS;

  testme1 = testme2;

  if ( testme1.isNull() ) return NOM_EXIT_SUCCESS;
  if ( testme2.isNull() ) return NOM_EXIT_SUCCESS;
  if ( testme2 == nom::Coords::null ) return NOM_EXIT_SUCCESS;

  return NOM_EXIT_SUCCESS;
}

nom::int32 do_coords_test2 ( void )
{
  NOM_LOG_TRACE(NOM);

  IntRect testme1 ( -1, -1, -1, -1 );
  FloatRect testme2 ( -1, -1, -1, -1 );

  NOM_DUMP_VAR(testme1);
  NOM_DUMP_VAR(testme2);

  if ( testme1 != IntRect::null ) return NOM_EXIT_FAILURE;
  if ( testme2 != FloatRect::null ) return NOM_EXIT_FAILURE;

  return NOM_EXIT_SUCCESS;
}

nom::int32 do_coords_test3 ( void )
{
  NOM_LOG_TRACE(NOM);

  Point2i testme1 ( -1, -1 );
  Point2f testme2 ( -1, -1 );

  NOM_DUMP_VAR(testme1);
  NOM_DUMP_VAR(testme2);

  if ( testme1 != Point2i::null ) return NOM_EXIT_FAILURE;
  if ( testme2 != Point2f::null ) return NOM_EXIT_FAILURE;

  return NOM_EXIT_SUCCESS;
}

nom::int32 do_coords_test4 ( void )
{
  return NOM_EXIT_SUCCESS;
}

nom::int32 main ( nom::int32 args_count, char* args[] )
{
  if ( do_color_test1() != NOM_EXIT_SUCCESS )
  {
    NOM_LOG_ERR ( NOM_UNIT_TEST, "Failed nom::Color unit test 1" );
    return NOM_EXIT_FAILURE;
  }

  if ( do_color_test2() != NOM_EXIT_SUCCESS )
  {
    NOM_LOG_ERR ( NOM_UNIT_TEST, "Failed nom::Color unit test 2" );
    return NOM_EXIT_FAILURE;
  }

  if ( do_color_test3() != NOM_EXIT_SUCCESS )
  {
    NOM_LOG_ERR ( NOM_UNIT_TEST, "Failed nom::Color unit test 3" );
    return NOM_EXIT_FAILURE;
  }

  if ( do_color_test4() != NOM_EXIT_SUCCESS )
  {
    NOM_LOG_ERR ( NOM_UNIT_TEST, "Failed nom::Color unit test 4" );
    return NOM_EXIT_FAILURE;
  }

  if ( do_coords_test1() != NOM_EXIT_SUCCESS )
  {
    NOM_LOG_ERR ( NOM_UNIT_TEST, "Failed nom::Coords unit test 1" );
    return NOM_EXIT_FAILURE;
  }

  if ( do_coords_test2() != NOM_EXIT_SUCCESS )
  {
    NOM_LOG_ERR ( NOM_UNIT_TEST, "Failed nom::Coords unit test 2" );
    return NOM_EXIT_FAILURE;
  }

  if ( do_coords_test3() != NOM_EXIT_SUCCESS )
  {
    NOM_LOG_ERR ( NOM_UNIT_TEST, "Failed nom::Coords unit test 3" );
    return NOM_EXIT_FAILURE;
  }

  if ( do_coords_test4() != NOM_EXIT_SUCCESS )
  {
    NOM_LOG_ERR ( NOM_UNIT_TEST, "Failed nom::Coords unit test 4" );
    return NOM_EXIT_FAILURE;
  }

  NOM_LOG_INFO ( NOM_UNIT_TEST, "Math Unit Tests: Pass!" );
  return NOM_EXIT_SUCCESS;
}
<|endoftext|>


<commit_before>/*=========================================================================
 *
 *  Copyright RTK Consortium
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *         http://www.apache.org/licenses/LICENSE-2.0.txt
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 *
 *=========================================================================*/

#include "rtkXRadImageIO.h"

#include <itkRawImageIO.h>
#include <itkMetaDataObject.h>

//--------------------------------------------------------------------
// Read Image Information
void rtk::XRadImageIO::ReadImageInformation()
{
  std::ifstream is;
  is.open(m_FileName.c_str());

  if(!is.is_open())
    itkExceptionMacro(<<"Could not open file " << m_FileName);

  SetNumberOfDimensions(3);
  std::string section="";
  while(!is.eof())
    {
    std::string line;
    std::getline(is, line);
    if(line.find('[')!=std::string::npos)
      {
      unsigned int pos1 = line.find('[');
      unsigned int pos2 = line.find(']');
      section = line.substr(pos1+1, pos2-pos1-1);
      }
    if(line.find('=')!=std::string::npos)
      {
      unsigned int pos       = line.find('=');
      std::string paramName  = line.substr(0,pos);
      std::string paramValue = line.substr(pos+1, line.length()-pos-1);

      if(paramName == std::string("CBCT.DimensionalAttributes.IDim"))
        SetDimensions(0, atoi(paramValue.c_str()));
      else if(paramName == std::string("CBCT.DimensionalAttributes.JDim"))
        SetDimensions(1, atoi(paramValue.c_str()));
      else if(paramName == std::string("CBCT.DimensionalAttributes.KDim"))
        SetDimensions(2, atoi(paramValue.c_str()));
      else if(paramName == std::string("CBCT.DimensionalAttributes.DataSize"))
        {
        if(atoi(paramValue.c_str())==3)
          SetComponentType(itk::ImageIOBase::FLOAT);
        if(atoi(paramValue.c_str())==6)
          SetComponentType(itk::ImageIOBase::USHORT);
        }
      else if(paramName == std::string("CBCT.DimensionalAttributes.PixelDimension_I_cm"))
        {
        double spacing = 10*atof(paramValue.c_str());
        SetSpacing(0, (spacing==0.)?1.:spacing);
        }
      else if(paramName == std::string("CBCT.DimensionalAttributes.PixelDimension_J_cm"))
        {
        double spacing = 10*atof(paramValue.c_str());
        SetSpacing(1, (spacing==0.)?1.:spacing);
        }
      else if(paramName == std::string("CBCT.DimensionalAttributes.PixelDimension_K_cm"))
        {
        double spacing = 10*atof(paramValue.c_str());
        SetSpacing(2, (spacing==0.)?1.:spacing);
        }
      else
        {
        paramName = section + std::string("_") + paramName;
        itk::EncapsulateMetaData<std::string>(this->GetMetaDataDictionary(),
                                              paramName.c_str(),
                                              paramValue);
        }
      }

    }
} ////

//--------------------------------------------------------------------
// Read Image Information
bool rtk::XRadImageIO::CanReadFile(const char* FileNameToRead)
{
  std::string                  filename(FileNameToRead);
  const std::string::size_type it = filename.find_last_of( "." );
  std::string                  fileExt( filename, it+1, filename.length() );

  if (fileExt != std::string("header") ) return false;
  return true;
} ////

//--------------------------------------------------------------------
// Read Image Content
void rtk::XRadImageIO::Read(void * buffer)
{
  // Adapted from itkRawImageIO
  std::string rawFileName( m_FileName, 0, m_FileName.size()-6);
  rawFileName += "img";

  std::ifstream is(rawFileName.c_str(), std::ios::binary);
  if(!is.is_open() )
    itkExceptionMacro(<<"Could not open file " << rawFileName);

  unsigned long numberOfBytesToBeRead = GetComponentSize();
  for(unsigned int i=0; i<GetNumberOfDimensions(); i++) numberOfBytesToBeRead *= GetDimensions(i);

  if(!this->ReadBufferAsBinary(is, buffer, numberOfBytesToBeRead) ) {
    itkExceptionMacro(<<"Read failed: Wanted "
                      << numberOfBytesToBeRead
                      << " bytes, but read "
                      << is.gcount() << " bytes.");
    }
  itkDebugMacro(<< "Reading Done");

  // Adapted from itkRawImageIO
    {
    using namespace itk;
    // Swap bytes if necessary
    if itkReadRawBytesAfterSwappingMacro( unsigned short, USHORT )
    else if itkReadRawBytesAfterSwappingMacro( short, SHORT )
    else if itkReadRawBytesAfterSwappingMacro( char, CHAR )
    else if itkReadRawBytesAfterSwappingMacro( unsigned char, UCHAR )
    else if itkReadRawBytesAfterSwappingMacro( unsigned int, UINT )
    else if itkReadRawBytesAfterSwappingMacro( int, INT )
    else if itkReadRawBytesAfterSwappingMacro( unsigned int, ULONG )
    else if itkReadRawBytesAfterSwappingMacro( int, LONG )
    else if itkReadRawBytesAfterSwappingMacro( float, FLOAT )
    else if itkReadRawBytesAfterSwappingMacro( double, DOUBLE );
    }
}

//--------------------------------------------------------------------
// Write Image Information
void rtk::XRadImageIO::WriteImageInformation(bool keepOfStream)
{
}

//--------------------------------------------------------------------
// Write Image Information
bool rtk::XRadImageIO::CanWriteFile(const char* FileNameToWrite)
{
  return false;
}

//--------------------------------------------------------------------
// Write Image
void rtk::XRadImageIO::Write(const void * buffer)
{
} ////
<commit_msg>STYLE: style issue fixed<commit_after>/*=========================================================================
 *
 *  Copyright RTK Consortium
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *         http://www.apache.org/licenses/LICENSE-2.0.txt
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 *
 *=========================================================================*/

#include "rtkXRadImageIO.h"

#include <itkRawImageIO.h>
#include <itkMetaDataObject.h>

//--------------------------------------------------------------------
// Read Image Information
void rtk::XRadImageIO::ReadImageInformation()
{
  std::ifstream is;
  is.open(m_FileName.c_str());

  if(!is.is_open())
    itkExceptionMacro(<<"Could not open file " << m_FileName);

  SetNumberOfDimensions(3);
  std::string section="";
  while(!is.eof())
    {
    std::string line;
    std::getline(is, line);
    if(line.find('[') != std::string::npos)
      {
      unsigned int pos1 = line.find('[');
      unsigned int pos2 = line.find(']');
      section = line.substr(pos1+1, pos2-pos1-1);
      }
    if(line.find('=') != std::string::npos)
      {
      unsigned int pos       = line.find('=');
      std::string paramName  = line.substr(0,pos);
      std::string paramValue = line.substr(pos+1, line.length()-pos-1);

      if(paramName == std::string("CBCT.DimensionalAttributes.IDim"))
        SetDimensions(0, atoi(paramValue.c_str()));
      else if(paramName == std::string("CBCT.DimensionalAttributes.JDim"))
        SetDimensions(1, atoi(paramValue.c_str()));
      else if(paramName == std::string("CBCT.DimensionalAttributes.KDim"))
        SetDimensions(2, atoi(paramValue.c_str()));
      else if(paramName == std::string("CBCT.DimensionalAttributes.DataSize"))
        {
        if(atoi(paramValue.c_str()) == 3)
          SetComponentType(itk::ImageIOBase::FLOAT);
        if(atoi(paramValue.c_str()) == 6)
          SetComponentType(itk::ImageIOBase::USHORT);
        }
      else if(paramName == std::string("CBCT.DimensionalAttributes.PixelDimension_I_cm"))
        {
        double spacing = 10*atof(paramValue.c_str());
        SetSpacing(0, (spacing==0.)?1.:spacing);
        }
      else if(paramName == std::string("CBCT.DimensionalAttributes.PixelDimension_J_cm"))
        {
        double spacing = 10*atof(paramValue.c_str());
        SetSpacing(1, (spacing==0.)?1.:spacing);
        }
      else if(paramName == std::string("CBCT.DimensionalAttributes.PixelDimension_K_cm"))
        {
        double spacing = 10*atof(paramValue.c_str());
        SetSpacing(2, (spacing==0.)?1.:spacing);
        }
      else
        {
        paramName = section + std::string("_") + paramName;
        itk::EncapsulateMetaData<std::string>(this->GetMetaDataDictionary(),
                                              paramName.c_str(),
                                              paramValue);
        }
      }

    }
} ////

//--------------------------------------------------------------------
// Read Image Information
bool rtk::XRadImageIO::CanReadFile(const char* FileNameToRead)
{
  std::string                  filename(FileNameToRead);
  const std::string::size_type it = filename.find_last_of( "." );
  std::string                  fileExt( filename, it+1, filename.length() );

  if (fileExt != std::string("header") ) return false;
  return true;
} ////

//--------------------------------------------------------------------
// Read Image Content
void rtk::XRadImageIO::Read(void * buffer)
{
  // Adapted from itkRawImageIO
  std::string rawFileName( m_FileName, 0, m_FileName.size()-6);
  rawFileName += "img";

  std::ifstream is(rawFileName.c_str(), std::ios::binary);
  if(!is.is_open() )
    itkExceptionMacro(<<"Could not open file " << rawFileName);

  unsigned long numberOfBytesToBeRead = GetComponentSize();
  for(unsigned int i=0; i<GetNumberOfDimensions(); i++) numberOfBytesToBeRead *= GetDimensions(i);

  if(!this->ReadBufferAsBinary(is, buffer, numberOfBytesToBeRead) ) {
    itkExceptionMacro(<<"Read failed: Wanted "
                      << numberOfBytesToBeRead
                      << " bytes, but read "
                      << is.gcount() << " bytes.");
    }
  itkDebugMacro(<< "Reading Done");

  // Adapted from itkRawImageIO
    {
    using namespace itk;
    // Swap bytes if necessary
    if itkReadRawBytesAfterSwappingMacro( unsigned short, USHORT )
    else if itkReadRawBytesAfterSwappingMacro( short, SHORT )
    else if itkReadRawBytesAfterSwappingMacro( char, CHAR )
    else if itkReadRawBytesAfterSwappingMacro( unsigned char, UCHAR )
    else if itkReadRawBytesAfterSwappingMacro( unsigned int, UINT )
    else if itkReadRawBytesAfterSwappingMacro( int, INT )
    else if itkReadRawBytesAfterSwappingMacro( unsigned int, ULONG )
    else if itkReadRawBytesAfterSwappingMacro( int, LONG )
    else if itkReadRawBytesAfterSwappingMacro( float, FLOAT )
    else if itkReadRawBytesAfterSwappingMacro( double, DOUBLE );
    }
}

//--------------------------------------------------------------------
// Write Image Information
void rtk::XRadImageIO::WriteImageInformation(bool keepOfStream)
{
}

//--------------------------------------------------------------------
// Write Image Information
bool rtk::XRadImageIO::CanWriteFile(const char* FileNameToWrite)
{
  return false;
}

//--------------------------------------------------------------------
// Write Image
void rtk::XRadImageIO::Write(const void * buffer)
{
} ////
<|endoftext|>


<commit_before>#include "arithmetics.hpp"

namespace arithmetics
{
	int add(int a, int b)
	{
		return a + b;
	}

	int add_buggy(int a, int b)
	{
		return a + b + 1;
	}
}

<commit_msg>Fix bug to see Travis succeed<commit_after>#include "arithmetics.hpp"

namespace arithmetics
{
	int add(int a, int b)
	{
		return a + b;
	}

	int add_buggy(int a, int b)
	{
		return a + b;
	}
}

<|endoftext|>


<commit_before>#ifndef HEADER_TEST_HPP
#define HEADER_TEST_HPP

#include <string.h>
#include <math.h>
#include <sstream>

#include "../src/pugixml.hpp"

inline bool test_string_equal(const char* lhs, const char* rhs)
{
	return (!lhs || !rhs) ? lhs == rhs : strcmp(lhs, rhs) == 0;
}

template <typename Node> inline bool test_node_name_value(const Node& node, const char* name, const char* value)
{
	return test_string_equal(node.name(), name) && test_string_equal(node.value(), value);
}

inline bool test_node(const pugi::xml_node& node, const char* contents, const char* indent, unsigned int flags)
{
	std::ostringstream oss;
	node.print(oss, indent, flags);

	return oss.str() == contents;
}

inline bool test_xpath_string(const pugi::xml_node& node, const char* query, const char* expected)
{
	pugi::xpath_query q(query);

	return q.evaluate_string(node) == expected;
}

inline bool test_xpath_boolean(const pugi::xml_node& node, const char* query, bool expected)
{
	pugi::xpath_query q(query);

	return q.evaluate_boolean(node) == expected;
}

inline bool test_xpath_number(const pugi::xml_node& node, const char* query, double expected)
{
	pugi::xpath_query q(query);

	return fabs(q.evaluate_number(node) - expected) < 1e-16f;
}

inline bool test_xpath_number_nan(const pugi::xml_node& node, const char* query)
{
	pugi::xpath_query q(query);

	double r = q.evaluate_number(node);

	return r != r;
}

inline bool test_xpath_fail_compile(const char* query)
{
	try
	{
		pugi::xpath_query q(query);
		return false;
	}
	catch (const pugi::xpath_exception&)
	{
		return true;
	}
}

struct test_runner
{
	test_runner(const char* name)
	{
		_name = name;
		_next = _tests;
		_tests = this;
	}

	virtual ~test_runner() {}

	virtual void run() = 0;

	const char* _name;
	test_runner* _next;

	static test_runner* _tests;
	static size_t _memory_fail_threshold;
};

struct dummy_fixture {};

#define TEST_FIXTURE(name, fixture) \
	struct test_runner_helper_##name: fixture \
	{ \
		void run(); \
	}; \
	static struct test_runner_##name: test_runner \
	{ \
		test_runner_##name(): test_runner(#name) {} \
		\
		virtual void run() \
		{ \
			test_runner_helper_##name helper; \
			helper.run(); \
		} \
	} test_runner_instance_##name; \
	void test_runner_helper_##name::run()

#define TEST(name) TEST_FIXTURE(name, dummy_fixture)

#define TEST_XML_FLAGS(name, xml, flags) \
	struct test_fixture_##name \
	{ \
		pugi::xml_document doc; \
		\
		test_fixture_##name() \
		{ \
			CHECK(doc.load(xml, flags)); \
		} \
		\
	private: \
		test_fixture_##name(const test_fixture_##name&); \
		test_fixture_##name& operator=(const test_fixture_##name&); \
	}; \
	\
	TEST_FIXTURE(name, test_fixture_##name)

#define TEST_XML(name, xml) TEST_XML_FLAGS(name, xml, pugi::parse_default)

#define CHECK_TEXT(condition, text) if (condition) ; else throw text

#define CHECK(condition) CHECK_TEXT(condition, #condition " is false")
#define CHECK_STRING(value, expected) CHECK_TEXT(test_string_equal(value, expected), #value " is not equal to " #expected)
#define CHECK_DOUBLE(value, expected) CHECK_TEXT(fabs(value - expected) < 1e-6, #value " is not equal to " #expected)
#define CHECK_NAME_VALUE(node, name, value) CHECK_TEXT(test_node_name_value(node, name, value), #node " name/value do not match " #name " and " #value)
#define CHECK_NODE_EX(node, expected, indent, flags) CHECK_TEXT(test_node(node, expected, indent, flags), #node " contents does not match " #expected)
#define CHECK_NODE(node, expected) CHECK_NODE_EX(node, expected, "", pugi::format_raw)

#define CHECK_XPATH_STRING(node, query, expected) CHECK_TEXT(test_xpath_string(node, query, expected), #query " does not evaluate to " #expected " in context " #node)
#define CHECK_XPATH_BOOLEAN(node, query, expected) CHECK_TEXT(test_xpath_boolean(node, query, expected), #query " does not evaluate to " #expected " in context " #node)
#define CHECK_XPATH_NUMBER(node, query, expected) CHECK_TEXT(test_xpath_number(node, query, expected), #query " does not evaluate to " #expected " in context " #node)
#define CHECK_XPATH_NUMBER_NAN(node, query) CHECK_TEXT(test_xpath_number_nan(node, query), #query " does not evaluate to NaN in context " #node)
#define CHECK_XPATH_FAIL(query) CHECK_TEXT(test_xpath_fail_compile(query), #query " should not compile")

#endif
<commit_msg>tests: Fixed MSVC6 compilation<commit_after>#ifndef HEADER_TEST_HPP
#define HEADER_TEST_HPP

#include <string.h>
#include <math.h>
#include <sstream>

#include "../src/pugixml.hpp"

inline bool test_string_equal(const char* lhs, const char* rhs)
{
	return (!lhs || !rhs) ? lhs == rhs : strcmp(lhs, rhs) == 0;
}

template <typename Node> inline bool test_node_name_value(const Node& node, const char* name, const char* value)
{
	return test_string_equal(node.name(), name) && test_string_equal(node.value(), value);
}

inline bool test_node(const pugi::xml_node& node, const char* contents, const char* indent, unsigned int flags)
{
	std::ostringstream oss;
	node.print(oss, indent, flags);

	return oss.str() == contents;
}

inline bool test_xpath_string(const pugi::xml_node& node, const char* query, const char* expected)
{
	pugi::xpath_query q(query);

	return q.evaluate_string(node) == expected;
}

inline bool test_xpath_boolean(const pugi::xml_node& node, const char* query, bool expected)
{
	pugi::xpath_query q(query);

	return q.evaluate_boolean(node) == expected;
}

inline bool test_xpath_number(const pugi::xml_node& node, const char* query, double expected)
{
	pugi::xpath_query q(query);

	return fabs(q.evaluate_number(node) - expected) < 1e-16f;
}

inline bool test_xpath_number_nan(const pugi::xml_node& node, const char* query)
{
	pugi::xpath_query q(query);

	double r = q.evaluate_number(node);

	return r != r;
}

inline bool test_xpath_fail_compile(const char* query)
{
	try
	{
		pugi::xpath_query q(query);
		return false;
	}
	catch (const pugi::xpath_exception&)
	{
		return true;
	}
}

struct test_runner
{
	test_runner(const char* name)
	{
		_name = name;
		_next = _tests;
		_tests = this;
	}

	virtual ~test_runner() {}

	virtual void run() = 0;

	const char* _name;
	test_runner* _next;

	static test_runner* _tests;
	static size_t _memory_fail_threshold;
};

struct dummy_fixture {};

#define TEST_FIXTURE(name, fixture) \
	struct test_runner_helper_##name: fixture \
	{ \
		void run(); \
	}; \
	static struct test_runner_##name: test_runner \
	{ \
		test_runner_##name(): test_runner(#name) {} \
		\
		virtual void run() \
		{ \
			test_runner_helper_##name helper; \
			helper.run(); \
		} \
	} test_runner_instance_##name; \
	void test_runner_helper_##name::run()

#define TEST(name) TEST_FIXTURE(name, dummy_fixture)

#define TEST_XML_FLAGS(name, xml, flags) \
	struct test_fixture_##name \
	{ \
		pugi::xml_document doc; \
		\
		test_fixture_##name() \
		{ \
			CHECK(doc.load(xml, flags)); \
		} \
		\
	private: \
		test_fixture_##name(const test_fixture_##name&); \
		test_fixture_##name& operator=(const test_fixture_##name&); \
	}; \
	\
	TEST_FIXTURE(name, test_fixture_##name)

#define TEST_XML(name, xml) TEST_XML_FLAGS(name, xml, pugi::parse_default)

#define CHECK_JOIN(text, file, line) text file #line
#define CHECK_JOIN2(text, file, line) CHECK_JOIN(text, file, line)
#define CHECK_TEXT(condition, text) if (condition) ; else throw CHECK_JOIN2(text, " at "__FILE__ ":", __LINE__)

#if defined(_MSC_VER) && _MSC_VER == 1200
#	define STR(value) "??" // MSVC 6.0 has troubles stringizing stuff with strings w/escaping inside
#else
#	define STR(value) #value
#endif

#define CHECK(condition) CHECK_TEXT(condition, STR(condition) " is false")
#define CHECK_STRING(value, expected) CHECK_TEXT(test_string_equal(value, expected), STR(value) " is not equal to " STR(expected))
#define CHECK_DOUBLE(value, expected) CHECK_TEXT(fabs(value - expected) < 1e-6, STR(value) " is not equal to " STR(expected))
#define CHECK_NAME_VALUE(node, name, value) CHECK_TEXT(test_node_name_value(node, name, value), STR(node) " name/value do not match " STR(name) " and " STR(value))
#define CHECK_NODE_EX(node, expected, indent, flags) CHECK_TEXT(test_node(node, expected, indent, flags), STR(node) " contents does not match " STR(expected))
#define CHECK_NODE(node, expected) CHECK_NODE_EX(node, expected, "", pugi::format_raw)

#define CHECK_XPATH_STRING(node, query, expected) CHECK_TEXT(test_xpath_string(node, query, expected), STR(query) " does not evaluate to " STR(expected) " in context " STR(node))
#define CHECK_XPATH_BOOLEAN(node, query, expected) CHECK_TEXT(test_xpath_boolean(node, query, expected), STR(query) " does not evaluate to " STR(expected) " in context " STR(node))
#define CHECK_XPATH_NUMBER(node, query, expected) CHECK_TEXT(test_xpath_number(node, query, expected), STR(query) " does not evaluate to " STR(expected) " in context " STR(node))
#define CHECK_XPATH_NUMBER_NAN(node, query) CHECK_TEXT(test_xpath_number_nan(node, query), STR(query) " does not evaluate to NaN in context " STR(node))
#define CHECK_XPATH_FAIL(query) CHECK_TEXT(test_xpath_fail_compile(query), STR(query) " should not compile")

#endif
<|endoftext|>