/*
 * SymbolCompareTest.cpp
 *
 *  Created on: 15. 02. 2021
 *      Author: Martin Prokopic
 */

#include "catch2/catch.hpp"

#include <alphabet/common/SymbolCompare.h>
#include <alphabet/EndSymbol.h>
#include <alphabet/MinimalEndSymbol.h>

// object::Object compares its value by std::type_index
namespace alphabet {
    class Exactly14Chars : public alphabet::EndSymbol { };
}

using alphabet::SymbolCompare;
using alphabet::MinimalEndSymbol;
using object::Object;

TEST_CASE ("SymbolCompare", "[unit][alphabet]") {
    SECTION ("basic char comparison test") {
        SymbolCompare < char > charCompare;

        REQUIRE ( charCompare('a', 'b') );
        REQUIRE_FALSE ( charCompare('b', 'a') );
        REQUIRE_FALSE ( charCompare('a', 'a') );
        REQUIRE ( charCompare(MinimalEndSymbol::instance<char>(), 'a') );
        REQUIRE ( charCompare(MinimalEndSymbol::instance<char>(), '\x01') );
    }

    SECTION ("object::Object comparison test") {
        SymbolCompare < Object > objectCompare;

        // if the following line fails, the test is non-representative
        CHECK ( Object(alphabet::Exactly14Chars()) < MinimalEndSymbol::instance<Object>() );

        REQUIRE ( objectCompare(Object('a'), Object('b')) );
        REQUIRE ( objectCompare(Object('\0'), Object('b')) );
        REQUIRE_FALSE ( objectCompare(Object('\0'), Object('\0')) );
        REQUIRE ( objectCompare(MinimalEndSymbol::instance<Object>(), Object(0)) );
        REQUIRE ( objectCompare(MinimalEndSymbol::instance<Object>(), Object(-10)) );
        REQUIRE ( objectCompare(MinimalEndSymbol::instance<Object>(), Object('\0')) );
        REQUIRE ( objectCompare(MinimalEndSymbol::instance<Object>(), Object("jablko")) );
        REQUIRE_FALSE ( objectCompare(MinimalEndSymbol::instance<Object>(), MinimalEndSymbol::instance<Object>()) );
        REQUIRE_FALSE ( objectCompare(Object(42), MinimalEndSymbol::instance<Object>()) );
        REQUIRE_FALSE ( objectCompare(Object(alphabet::Exactly14Chars()), MinimalEndSymbol::instance<Object>() ));
        REQUIRE ( objectCompare(MinimalEndSymbol::instance<Object>(), Object(alphabet::Exactly14Chars()) ));
        REQUIRE_FALSE ( objectCompare(Object(alphabet::Exactly14Chars()), MinimalEndSymbol::instance<Object>() ));
    }
}
