Initial commit of mtgonline project
This commit is contained in:
@@ -0,0 +1,89 @@
|
||||
# NOTE: Qt modules for tests are defined centrally in cmake/FindQtRuntime.cmake (the _TEST_NEEDED variable).
|
||||
# If a new test needs additional Qt modules, add them there — not in individual test CMakeLists.txt files.
|
||||
enable_testing()
|
||||
|
||||
add_test(NAME dummy_test COMMAND dummy_test)
|
||||
add_test(NAME expression_test COMMAND expression_test)
|
||||
add_test(NAME clamped_arithmetic_test COMMAND clamped_arithmetic_test)
|
||||
add_test(NAME test_age_formatting COMMAND test_age_formatting)
|
||||
add_test(NAME password_hash_test COMMAND password_hash_test)
|
||||
add_test(NAME server_card_counter_test COMMAND server_card_counter_test)
|
||||
add_test(NAME server_counter_test COMMAND server_counter_test)
|
||||
|
||||
add_test(NAME deck_hash_performance_test COMMAND deck_hash_performance_test)
|
||||
set_tests_properties(deck_hash_performance_test PROPERTIES TIMEOUT 5)
|
||||
|
||||
# Find GTest
|
||||
|
||||
add_executable(dummy_test dummy_test.cpp)
|
||||
add_executable(expression_test expression_test.cpp)
|
||||
add_executable(clamped_arithmetic_test clamped_arithmetic_test.cpp)
|
||||
add_executable(test_age_formatting test_age_formatting.cpp)
|
||||
add_executable(password_hash_test password_hash_test.cpp)
|
||||
add_executable(deck_hash_performance_test deck_hash_performance_test.cpp)
|
||||
add_executable(server_card_counter_test server_card_counter_test.cpp)
|
||||
add_executable(server_counter_test server_counter_test.cpp)
|
||||
|
||||
find_package(GTest)
|
||||
|
||||
if(NOT GTEST_FOUND)
|
||||
if(NOT EXISTS "${CMAKE_BINARY_DIR}/gtest-build")
|
||||
message(STATUS "Downloading googletest")
|
||||
configure_file(
|
||||
"${CMAKE_SOURCE_DIR}/cmake/gtest-CMakeLists.txt.in" "${CMAKE_BINARY_DIR}/gtest-download/CMakeLists.txt"
|
||||
)
|
||||
execute_process(
|
||||
COMMAND ${CMAKE_COMMAND} -G "${CMAKE_GENERATOR}" . WORKING_DIRECTORY ${CMAKE_BINARY_DIR}/gtest-download
|
||||
)
|
||||
execute_process(COMMAND ${CMAKE_COMMAND} --build . WORKING_DIRECTORY ${CMAKE_BINARY_DIR}/gtest-download)
|
||||
else()
|
||||
message(STATUS "GoogleTest directory exists")
|
||||
endif()
|
||||
|
||||
# Add gtest directly to our build
|
||||
add_subdirectory(${CMAKE_BINARY_DIR}/gtest-src ${CMAKE_BINARY_DIR}/gtest-build EXCLUDE_FROM_ALL)
|
||||
|
||||
# Add the gtest include directory, since gtest
|
||||
# doesn't add that dependency to its gtest target
|
||||
target_include_directories(gtest INTERFACE "$<BUILD_INTERFACE:${CMAKE_BINARY_DIR}/gtest-src/include>")
|
||||
|
||||
set(GTEST_INCLUDE_DIRS "${CMAKE_BINARY_DIR}/gtest-src/include")
|
||||
set(GTEST_BOTH_LIBRARIES gtest)
|
||||
add_dependencies(dummy_test gtest)
|
||||
add_dependencies(expression_test gtest)
|
||||
add_dependencies(clamped_arithmetic_test gtest)
|
||||
add_dependencies(test_age_formatting gtest)
|
||||
add_dependencies(password_hash_test gtest)
|
||||
add_dependencies(deck_hash_performance_test gtest)
|
||||
add_dependencies(server_card_counter_test gtest)
|
||||
add_dependencies(server_counter_test gtest)
|
||||
endif()
|
||||
|
||||
include_directories(${GTEST_INCLUDE_DIRS})
|
||||
target_link_libraries(dummy_test Threads::Threads ${GTEST_BOTH_LIBRARIES})
|
||||
target_link_libraries(expression_test libcockatrice_utility Threads::Threads ${GTEST_BOTH_LIBRARIES} ${TEST_QT_MODULES})
|
||||
target_link_libraries(
|
||||
clamped_arithmetic_test libcockatrice_utility Threads::Threads ${GTEST_BOTH_LIBRARIES} ${TEST_QT_MODULES}
|
||||
)
|
||||
target_link_libraries(
|
||||
test_age_formatting libcockatrice_utility Threads::Threads ${GTEST_BOTH_LIBRARIES} ${TEST_QT_MODULES}
|
||||
)
|
||||
target_link_libraries(
|
||||
password_hash_test libcockatrice_utility Threads::Threads ${GTEST_BOTH_LIBRARIES} ${TEST_QT_MODULES}
|
||||
)
|
||||
target_link_libraries(
|
||||
deck_hash_performance_test libcockatrice_deck_list libcockatrice_utility Threads::Threads ${GTEST_BOTH_LIBRARIES}
|
||||
${TEST_QT_MODULES}
|
||||
)
|
||||
target_link_libraries(
|
||||
server_card_counter_test libcockatrice_network Threads::Threads ${GTEST_BOTH_LIBRARIES} ${TEST_QT_MODULES}
|
||||
)
|
||||
target_link_libraries(
|
||||
server_counter_test libcockatrice_network Threads::Threads ${GTEST_BOTH_LIBRARIES} ${TEST_QT_MODULES}
|
||||
)
|
||||
|
||||
add_subdirectory(card_zone_algorithms)
|
||||
add_subdirectory(carddatabase)
|
||||
add_subdirectory(loading_from_clipboard)
|
||||
add_subdirectory(movecard_tests)
|
||||
add_subdirectory(oracle)
|
||||
@@ -0,0 +1,15 @@
|
||||
add_executable(card_zone_algorithms_test card_zone_algorithms_test.cpp)
|
||||
|
||||
target_include_directories(card_zone_algorithms_test PRIVATE ${CMAKE_SOURCE_DIR}/cockatrice/src/game/zones)
|
||||
|
||||
target_link_libraries(
|
||||
card_zone_algorithms_test
|
||||
PRIVATE Threads::Threads
|
||||
PRIVATE ${GTEST_BOTH_LIBRARIES}
|
||||
)
|
||||
|
||||
add_test(NAME card_zone_algorithms_test COMMAND card_zone_algorithms_test)
|
||||
|
||||
if(NOT GTEST_FOUND)
|
||||
add_dependencies(card_zone_algorithms_test gtest)
|
||||
endif()
|
||||
@@ -0,0 +1,159 @@
|
||||
#include "card_zone_algorithms.h"
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
#include <vector>
|
||||
|
||||
struct MockCardRef
|
||||
{
|
||||
};
|
||||
|
||||
struct MockCard
|
||||
{
|
||||
int idSet = 0;
|
||||
bool idWasCalled = false;
|
||||
MockCardRef cardRefSet{};
|
||||
bool cardRefWasCalled = false;
|
||||
bool resetStateCalled = false;
|
||||
bool resetStateKeepAnnotations = false;
|
||||
bool visibleSet = false;
|
||||
|
||||
void setId(int id)
|
||||
{
|
||||
idSet = id;
|
||||
idWasCalled = true;
|
||||
}
|
||||
|
||||
void setCardRef(MockCardRef ref)
|
||||
{
|
||||
cardRefSet = ref;
|
||||
cardRefWasCalled = true;
|
||||
}
|
||||
|
||||
void resetState(bool keepAnnotations)
|
||||
{
|
||||
resetStateCalled = true;
|
||||
resetStateKeepAnnotations = keepAnnotations;
|
||||
}
|
||||
|
||||
void setVisible(bool visible)
|
||||
{
|
||||
visibleSet = visible;
|
||||
}
|
||||
};
|
||||
|
||||
class MockCardList
|
||||
{
|
||||
std::vector<MockCard *> cards;
|
||||
bool contentsKnown;
|
||||
|
||||
public:
|
||||
explicit MockCardList(bool _contentsKnown) : contentsKnown(_contentsKnown)
|
||||
{
|
||||
}
|
||||
|
||||
int size() const
|
||||
{
|
||||
return static_cast<int>(cards.size());
|
||||
}
|
||||
|
||||
void insert(int index, MockCard *card)
|
||||
{
|
||||
cards.insert(cards.begin() + index, card);
|
||||
}
|
||||
|
||||
bool getContentsKnown() const
|
||||
{
|
||||
return contentsKnown;
|
||||
}
|
||||
|
||||
MockCard *at(int index) const
|
||||
{
|
||||
return cards.at(index);
|
||||
}
|
||||
};
|
||||
|
||||
class AddCardAlgorithmTest : public ::testing::Test
|
||||
{
|
||||
protected:
|
||||
MockCardList knownList{true};
|
||||
MockCardList unknownList{false};
|
||||
};
|
||||
|
||||
TEST_F(AddCardAlgorithmTest, NegativeIndexClampsToEnd)
|
||||
{
|
||||
MockCard a, b;
|
||||
CardZoneAlgorithms::addCardToList(knownList, &a, 0, false);
|
||||
CardZoneAlgorithms::addCardToList(knownList, &b, -1, false);
|
||||
|
||||
EXPECT_EQ(knownList.at(0), &a);
|
||||
EXPECT_EQ(knownList.at(1), &b);
|
||||
EXPECT_EQ(knownList.size(), 2);
|
||||
}
|
||||
|
||||
TEST_F(AddCardAlgorithmTest, IndexBeyondSizeClampsToEnd)
|
||||
{
|
||||
MockCard a, b;
|
||||
CardZoneAlgorithms::addCardToList(knownList, &a, 0, false);
|
||||
CardZoneAlgorithms::addCardToList(knownList, &b, 999, false);
|
||||
|
||||
EXPECT_EQ(knownList.at(0), &a);
|
||||
EXPECT_EQ(knownList.at(1), &b);
|
||||
EXPECT_EQ(knownList.size(), 2);
|
||||
}
|
||||
|
||||
TEST_F(AddCardAlgorithmTest, ContentsKnownPreservesIdentity)
|
||||
{
|
||||
MockCard card;
|
||||
CardZoneAlgorithms::addCardToList(knownList, &card, 0, false);
|
||||
|
||||
EXPECT_FALSE(card.idWasCalled);
|
||||
EXPECT_FALSE(card.cardRefWasCalled);
|
||||
EXPECT_TRUE(card.visibleSet);
|
||||
}
|
||||
|
||||
TEST_F(AddCardAlgorithmTest, ContentsUnknownClearsIdentity)
|
||||
{
|
||||
MockCard card;
|
||||
CardZoneAlgorithms::addCardToList(unknownList, &card, 0, false);
|
||||
|
||||
EXPECT_TRUE(card.idWasCalled);
|
||||
EXPECT_EQ(card.idSet, -1);
|
||||
EXPECT_TRUE(card.cardRefWasCalled);
|
||||
}
|
||||
|
||||
TEST_F(AddCardAlgorithmTest, MidListInsertionPreservesOrder)
|
||||
{
|
||||
MockCard a, b, c;
|
||||
CardZoneAlgorithms::addCardToList(knownList, &a, 0, false);
|
||||
CardZoneAlgorithms::addCardToList(knownList, &b, 1, false);
|
||||
CardZoneAlgorithms::addCardToList(knownList, &c, 1, false);
|
||||
|
||||
EXPECT_EQ(knownList.size(), 3);
|
||||
EXPECT_EQ(knownList.at(0), &a);
|
||||
EXPECT_EQ(knownList.at(1), &c);
|
||||
EXPECT_EQ(knownList.at(2), &b);
|
||||
}
|
||||
|
||||
TEST_F(AddCardAlgorithmTest, KeepAnnotationsFalsePassedThrough)
|
||||
{
|
||||
MockCard card;
|
||||
CardZoneAlgorithms::addCardToList(knownList, &card, 0, false);
|
||||
|
||||
EXPECT_TRUE(card.resetStateCalled);
|
||||
EXPECT_FALSE(card.resetStateKeepAnnotations);
|
||||
}
|
||||
|
||||
TEST_F(AddCardAlgorithmTest, KeepAnnotationsTruePassedThrough)
|
||||
{
|
||||
MockCard card;
|
||||
CardZoneAlgorithms::addCardToList(knownList, &card, 0, true);
|
||||
|
||||
EXPECT_TRUE(card.resetStateCalled);
|
||||
EXPECT_TRUE(card.resetStateKeepAnnotations);
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
::testing::InitGoogleTest(&argc, argv);
|
||||
return RUN_ALL_TESTS();
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
cmake_minimum_required(VERSION 3.16)
|
||||
project(CardDatabaseTests VERSION "${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}.${PROJECT_VERSION_PATCH}")
|
||||
|
||||
# ------------------------
|
||||
# Definitions
|
||||
# ------------------------
|
||||
add_definitions("-DCARDDB_DATADIR=\"${CMAKE_CURRENT_SOURCE_DIR}/data/\"")
|
||||
|
||||
# ------------------------
|
||||
# Card Database Test
|
||||
# ------------------------
|
||||
add_executable(carddatabase_test ${MOCKS_SOURCES} ${VERSION_STRING_CPP} carddatabase_test.cpp mocks.cpp)
|
||||
|
||||
target_link_libraries(
|
||||
carddatabase_test
|
||||
PRIVATE libcockatrice_card
|
||||
PRIVATE Threads::Threads
|
||||
PRIVATE ${GTEST_BOTH_LIBRARIES}
|
||||
PRIVATE ${TEST_QT_MODULES}
|
||||
)
|
||||
|
||||
add_test(NAME carddatabase_test COMMAND carddatabase_test)
|
||||
|
||||
# ------------------------
|
||||
# Filter String Test
|
||||
# (guard must match the condition for libcockatrice_filters in the root CMakeLists.txt)
|
||||
# ------------------------
|
||||
if(WITH_ORACLE OR WITH_CLIENT)
|
||||
add_executable(filter_string_test ${MOCKS_SOURCES} ${VERSION_STRING_CPP} filter_string_test.cpp mocks.cpp)
|
||||
|
||||
target_link_libraries(
|
||||
filter_string_test
|
||||
PRIVATE libcockatrice_filters
|
||||
PRIVATE Threads::Threads
|
||||
PRIVATE ${GTEST_BOTH_LIBRARIES}
|
||||
PRIVATE ${TEST_QT_MODULES}
|
||||
)
|
||||
|
||||
add_test(NAME filter_string_test COMMAND filter_string_test)
|
||||
|
||||
if(NOT GTEST_FOUND)
|
||||
add_dependencies(filter_string_test gtest)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# ------------------------
|
||||
# Dependencies on gtest
|
||||
# ------------------------
|
||||
if(NOT GTEST_FOUND)
|
||||
add_dependencies(carddatabase_test gtest)
|
||||
endif()
|
||||
@@ -0,0 +1,42 @@
|
||||
#include "mocks.h"
|
||||
#include "test_card_database_path_provider.h"
|
||||
|
||||
#include "gtest/gtest.h"
|
||||
#include <libcockatrice/interfaces/noop_card_preference_provider.h>
|
||||
#include <libcockatrice/interfaces/noop_card_set_priority_controller.h>
|
||||
|
||||
namespace
|
||||
{
|
||||
|
||||
TEST(CardDatabaseTest, LoadXml)
|
||||
{
|
||||
CardDatabase *db = new CardDatabase(nullptr, new NoopCardPreferenceProvider(), new TestCardDatabasePathProvider(),
|
||||
new NoopCardSetPriorityController());
|
||||
|
||||
// ensure the card database is empty at start
|
||||
ASSERT_EQ(0, db->getCardList().size()) << "Cards not empty at start";
|
||||
ASSERT_EQ(0, db->getSetList().size()) << "Sets not empty at start";
|
||||
ASSERT_EQ(0, db->query()->getAllMainCardTypes().size()) << "Types not empty at start";
|
||||
ASSERT_EQ(NotLoaded, db->getLoadStatus()) << "Incorrect status at start";
|
||||
|
||||
// load dummy cards and test result
|
||||
db->loadCardDatabases();
|
||||
ASSERT_EQ(9, db->getCardList().size()) << "Wrong card count after load";
|
||||
ASSERT_EQ(5, db->getSetList().size()) << "Wrong sets count after load";
|
||||
ASSERT_EQ(3, db->query()->getAllMainCardTypes().size()) << "Wrong types count after load";
|
||||
ASSERT_EQ(Ok, db->getLoadStatus()) << "Wrong status after load";
|
||||
|
||||
// ensure the card database is empty after clear()
|
||||
db->clear();
|
||||
ASSERT_EQ(0, db->getCardList().size()) << "Cards not empty after clear";
|
||||
ASSERT_EQ(0, db->getSetList().size()) << "Sets not empty after clear";
|
||||
ASSERT_EQ(0, db->query()->getAllMainCardTypes().size()) << "Types not empty after clear";
|
||||
ASSERT_EQ(NotLoaded, db->getLoadStatus()) << "Incorrect status after clear";
|
||||
}
|
||||
} // namespace
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
::testing::InitGoogleTest(&argc, argv);
|
||||
return RUN_ALL_TESTS();
|
||||
}
|
||||
@@ -0,0 +1,82 @@
|
||||
#include "mocks.h"
|
||||
#include "test_card_database_path_provider.h"
|
||||
|
||||
#include "gtest/gtest.h"
|
||||
#include <libcockatrice/filters/filter_string.h>
|
||||
#include <libcockatrice/interfaces/noop_card_preference_provider.h>
|
||||
#include <libcockatrice/interfaces/noop_card_set_priority_controller.h>
|
||||
|
||||
#define QUERY(name, card, query, match) \
|
||||
TEST_F(CardQuery, name) \
|
||||
{ \
|
||||
ASSERT_EQ(FilterString(query).check(card), match); \
|
||||
}
|
||||
|
||||
namespace
|
||||
{
|
||||
|
||||
class CardQuery : public ::testing::Test
|
||||
{
|
||||
protected:
|
||||
void SetUp() override
|
||||
{
|
||||
CardDatabase *db = new CardDatabase(nullptr, new NoopCardPreferenceProvider(),
|
||||
new TestCardDatabasePathProvider(), new NoopCardSetPriorityController());
|
||||
db->loadCardDatabases();
|
||||
|
||||
cat = db->query()->getCardBySimpleName("Cat");
|
||||
notDeadAfterAll = db->query()->getCardBySimpleName("Not Dead");
|
||||
truth = db->query()->getCardBySimpleName("Truth");
|
||||
doctor = db->query()->getCardBySimpleName("Doctor");
|
||||
}
|
||||
// void TearDown() override {}
|
||||
|
||||
CardData cat;
|
||||
CardData notDeadAfterAll;
|
||||
CardData truth;
|
||||
CardData doctor;
|
||||
};
|
||||
|
||||
QUERY(Empty, cat, "", true)
|
||||
QUERY(Typing, cat, "t", true)
|
||||
|
||||
QUERY(NonMatchingType, cat, "t:kithkin", false)
|
||||
QUERY(MatchingType, cat, "t:creature", true)
|
||||
QUERY(MatchingCreatureType, cat, "t:cat", true)
|
||||
QUERY(PartialMatchingType, cat, "t:ca", false)
|
||||
QUERY(MatchingMultiWordType, doctor, "t:\"Time Lord\"", true)
|
||||
QUERY(Not1, cat, "NOT t:kithkin", true)
|
||||
QUERY(Not2, cat, "NOT t:creature", false)
|
||||
QUERY(NonKeyword1, cat, "not t:kithkin", false)
|
||||
QUERY(NonKeyword2, cat, "t:bat or t:creature", false)
|
||||
QUERY(NonKeyword3, notDeadAfterAll, "not dead", true)
|
||||
QUERY(NonKeyword4, truth, "truth or trail", false)
|
||||
QUERY(Case, cat, "t:cReAtUrE", true)
|
||||
|
||||
QUERY(And, cat, "t:creature t:creature", true)
|
||||
QUERY(And2, cat, "t:creature t:sorcery", false)
|
||||
|
||||
QUERY(Or, cat, "t:bat OR t:creature", true)
|
||||
|
||||
QUERY(Cmc1, cat, "cmc=2", true)
|
||||
QUERY(Cmc2, cat, "cmc>3", false)
|
||||
QUERY(Cmc3, cat, "cmc>1", true)
|
||||
|
||||
QUERY(Quotes, cat, "t:\"creature\"", true)
|
||||
|
||||
QUERY(Field, cat, "pt:\"3/3\"", true)
|
||||
|
||||
QUERY(Color1, cat, "c:g", true)
|
||||
QUERY(Color2, cat, "c:gw", true)
|
||||
QUERY(Color3, cat, "c!g", true)
|
||||
QUERY(Color4, cat, "c!gw", false)
|
||||
|
||||
QUERY(BracketNextToUnquotedString, cat, "(o:woof OR o:meow)", true)
|
||||
|
||||
} // namespace
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
::testing::InitGoogleTest(&argc, argv);
|
||||
return RUN_ALL_TESTS();
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
|
||||
#include "mocks.h"
|
||||
|
||||
void CardPictureLoader::clearPixmapCache(CardInfoPtr /* card */)
|
||||
{
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
/*
|
||||
* Beware of this preprocessor hack used to redefine the settingCache class
|
||||
* instead of including it and all of its dependencies.
|
||||
* Always set header guards of mocked objects before including any headers
|
||||
* with mocked objects.
|
||||
*/
|
||||
|
||||
#define PICTURELOADER_H
|
||||
|
||||
#include <libcockatrice/card/database/card_database.h>
|
||||
|
||||
class CardPictureLoader
|
||||
{
|
||||
public:
|
||||
static void clearPixmapCache(CardInfoPtr card);
|
||||
};
|
||||
@@ -0,0 +1,28 @@
|
||||
#ifndef COCKATRICE_TEST_CARD_DATABASE_PATH_PROVIDER_H
|
||||
#define COCKATRICE_TEST_CARD_DATABASE_PATH_PROVIDER_H
|
||||
|
||||
#include <libcockatrice/interfaces/interface_card_database_path_provider.h>
|
||||
|
||||
class TestCardDatabasePathProvider : public ICardDatabasePathProvider
|
||||
{
|
||||
|
||||
public:
|
||||
QString getCardDatabasePath() const override
|
||||
{
|
||||
return QString("%1/cards.xml").arg(CARDDB_DATADIR);
|
||||
}
|
||||
QString getCustomCardDatabasePath() const override
|
||||
{
|
||||
return QString("%1/customsets/").arg(CARDDB_DATADIR);
|
||||
}
|
||||
QString getTokenDatabasePath() const override
|
||||
{
|
||||
return QString("%1/tokens.xml").arg(CARDDB_DATADIR);
|
||||
}
|
||||
QString getSpoilerCardDatabasePath() const override
|
||||
{
|
||||
return QString("%1/spoiler.xml").arg(CARDDB_DATADIR);
|
||||
}
|
||||
};
|
||||
|
||||
#endif // COCKATRICE_TEST_CARD_DATABASE_PATH_PROVIDER_H
|
||||
@@ -0,0 +1,44 @@
|
||||
/** @file clamped_arithmetic_test.cpp
|
||||
* @brief Tests for shared helpers in clamped_arithmetic.h.
|
||||
* @ingroup Tests
|
||||
*/
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
#include <libcockatrice/utility/clamped_arithmetic.h>
|
||||
#include <limits>
|
||||
|
||||
TEST(AddClamped, AddsWithinBounds)
|
||||
{
|
||||
EXPECT_EQ(addClamped(5, 3, 0, 100), 8);
|
||||
EXPECT_EQ(addClamped(10, -3, 0, 100), 7);
|
||||
}
|
||||
|
||||
TEST(AddClamped, ClampsToUpperAndLowerBound)
|
||||
{
|
||||
EXPECT_EQ(addClamped(99, 5, 0, 100), 100); // saturates at max
|
||||
EXPECT_EQ(addClamped(2, -10, 0, 100), 0); // saturates at min
|
||||
EXPECT_EQ(addClamped(999, 1, 0, 999), 999); // crossing the counter cap holds at the bound
|
||||
}
|
||||
|
||||
TEST(AddClamped, IntOverflowDoesNotWrap)
|
||||
{
|
||||
// The 64-bit intermediate must prevent signed-int overflow UB.
|
||||
constexpr int intMax = std::numeric_limits<int>::max();
|
||||
constexpr int intMin = std::numeric_limits<int>::min();
|
||||
EXPECT_EQ(addClamped(intMax, 1, intMin, intMax), intMax);
|
||||
EXPECT_EQ(addClamped(intMax, intMax, intMin, intMax), intMax);
|
||||
}
|
||||
|
||||
TEST(AddClamped, IntUnderflowDoesNotWrap)
|
||||
{
|
||||
constexpr int intMax = std::numeric_limits<int>::max();
|
||||
constexpr int intMin = std::numeric_limits<int>::min();
|
||||
EXPECT_EQ(addClamped(intMin, -1, intMin, intMax), intMin);
|
||||
EXPECT_EQ(addClamped(intMin, intMin, intMin, intMax), intMin);
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
::testing::InitGoogleTest(&argc, argv);
|
||||
return RUN_ALL_TESTS();
|
||||
}
|
||||
@@ -0,0 +1,81 @@
|
||||
#include "gtest/gtest.h"
|
||||
#include <QDebug>
|
||||
#include <libcockatrice/deck_list/deck_list.h>
|
||||
|
||||
static constexpr int amount = 1e5;
|
||||
QString repeatDeck;
|
||||
QString numberDeck;
|
||||
QString uniquesDeck;
|
||||
QString uniquesXorDeck;
|
||||
QString duplicatesDeck;
|
||||
|
||||
TEST(DeckHashTest, RepeatTest)
|
||||
{
|
||||
DeckList decklist(repeatDeck);
|
||||
for (int i = 0; i < amount; ++i) {
|
||||
decklist.getDeckHash();
|
||||
decklist.refreshDeckHash();
|
||||
}
|
||||
auto hash = decklist.getDeckHash().toStdString();
|
||||
ASSERT_EQ(hash, "5cac19qm") << "The hash does not match!";
|
||||
}
|
||||
|
||||
TEST(DeckHashTest, NumberTest)
|
||||
{
|
||||
DeckList decklist(numberDeck);
|
||||
auto hash = decklist.getDeckHash().toStdString();
|
||||
ASSERT_EQ(hash, "e0m38p19") << "The hash does not match!";
|
||||
}
|
||||
|
||||
TEST(DeckHashTest, UniquesTest)
|
||||
{
|
||||
DeckList decklist(uniquesDeck);
|
||||
auto hash = decklist.getDeckHash().toStdString();
|
||||
ASSERT_EQ(hash, "88prk025") << "The hash does not match!";
|
||||
}
|
||||
|
||||
TEST(DeckHashTest, UniquesTestXor)
|
||||
{
|
||||
DeckList decklist(uniquesXorDeck);
|
||||
auto hash = decklist.getDeckHash().toStdString();
|
||||
ASSERT_EQ(hash, "hkn6q4pf") << "The hash does not match!";
|
||||
}
|
||||
|
||||
TEST(DeckHashTest, DuplicatesTest)
|
||||
{
|
||||
DeckList decklist(duplicatesDeck);
|
||||
auto hash = decklist.getDeckHash().toStdString();
|
||||
ASSERT_EQ(hash, "ekt6tg1h") << "The hash does not match!";
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
const QString deckStart =
|
||||
R"(<?xml version="1.0"?><cockatrice_deck version="1"><deckname></deckname><comments></comments><zone name="main">)";
|
||||
const QString deckEnd = R"(</zone></cockatrice_deck>)";
|
||||
|
||||
repeatDeck =
|
||||
deckStart +
|
||||
R"(<card number="1" name="Mountain"/><card number="2" name="Island"/></zone><zone name="side"><card number="3" name="Forest"/>)" +
|
||||
deckEnd;
|
||||
numberDeck = deckStart + QString(R"(<card number="%1" name="Island"/>)").arg(amount) + deckEnd;
|
||||
|
||||
QStringList deckString{deckStart};
|
||||
QStringList deckStringXor = deckString;
|
||||
int len = QString::number(amount).length();
|
||||
for (int i = 0; i < amount; ++i) {
|
||||
// creates already sorted list
|
||||
deckString << R"(<card number="1" name="card )" << QString::number(i).rightJustified(len, '0') << R"("/>)";
|
||||
// xor in order to mess with sorting
|
||||
deckStringXor << R"(<card number="1" name="card )" << QString::number(i ^ amount) << R"("/>)";
|
||||
}
|
||||
deckString << deckEnd;
|
||||
deckStringXor << deckEnd;
|
||||
uniquesDeck = deckString.join("");
|
||||
uniquesXorDeck = deckStringXor.join("");
|
||||
|
||||
duplicatesDeck = deckStart + QString(R"(<card number="1" name="card"/>)").repeated(amount) + deckEnd;
|
||||
|
||||
::testing::InitGoogleTest(&argc, argv);
|
||||
return RUN_ALL_TESTS();
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
namespace
|
||||
{
|
||||
class FooTest : public ::testing::Test
|
||||
{
|
||||
};
|
||||
|
||||
TEST(DummyTest, Works)
|
||||
{
|
||||
ASSERT_EQ(1, 1) << "One is not equal to one";
|
||||
}
|
||||
} // namespace
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
::testing::InitGoogleTest(&argc, argv);
|
||||
return RUN_ALL_TESTS();
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
#include "gtest/gtest.h"
|
||||
#include <QtMath>
|
||||
#include <libcockatrice/utility/expression.h>
|
||||
|
||||
#define TEST_EXPR(name, a, b) \
|
||||
TEST(ExpressionTest, name) \
|
||||
{ \
|
||||
Expression exp(8); \
|
||||
ASSERT_EQ(exp.parse(a), b) << a; \
|
||||
}
|
||||
|
||||
namespace
|
||||
{
|
||||
|
||||
TEST_EXPR(Number, "1", 1)
|
||||
TEST_EXPR(Multiply, "2*2", 4)
|
||||
TEST_EXPR(Whitespace, "3 * 3", 9)
|
||||
TEST_EXPR(Powers, "2^8", 256)
|
||||
TEST_EXPR(OrderOfOperations, "2+2*2", 6)
|
||||
TEST_EXPR(Fn, "2*cos(1)", 2 * qCos(1))
|
||||
TEST_EXPR(Variable, "x / 2", 4)
|
||||
TEST_EXPR(Negative, "-2 * 2", -4)
|
||||
TEST_EXPR(UnknownFnReturnsZero, "blah(22)", 0)
|
||||
|
||||
} // namespace
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
::testing::InitGoogleTest(&argc, argv);
|
||||
return RUN_ALL_TESTS();
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
add_definitions("-DCARDDB_DATADIR=\"${CMAKE_CURRENT_SOURCE_DIR}/data/\"")
|
||||
add_executable(loading_from_clipboard_test ${VERSION_STRING_CPP} clipboard_testing.cpp loading_from_clipboard_test.cpp)
|
||||
|
||||
if(NOT GTEST_FOUND)
|
||||
add_dependencies(loading_from_clipboard_test gtest)
|
||||
endif()
|
||||
|
||||
target_link_libraries(
|
||||
loading_from_clipboard_test libcockatrice_deck_list libcockatrice_card Threads::Threads ${GTEST_BOTH_LIBRARIES}
|
||||
${TEST_QT_MODULES}
|
||||
)
|
||||
add_test(NAME loading_from_clipboard_test COMMAND loading_from_clipboard_test)
|
||||
@@ -0,0 +1,55 @@
|
||||
#include "clipboard_testing.h"
|
||||
|
||||
#include <QTextStream>
|
||||
#include <libcockatrice/card/import/card_name_normalizer.h>
|
||||
#include <libcockatrice/deck_list/tree/deck_list_card_node.h>
|
||||
|
||||
DeckList getDeckList(const QString &clipboard)
|
||||
{
|
||||
DeckList deckList;
|
||||
QString cp(clipboard);
|
||||
QTextStream stream(&cp); // text stream requires local copy
|
||||
deckList.loadFromStream_Plain(stream, false, CardNameNormalizer());
|
||||
return deckList;
|
||||
}
|
||||
|
||||
void testEmpty(const QString &clipboard)
|
||||
{
|
||||
DeckList deckList = getDeckList(clipboard);
|
||||
|
||||
ASSERT_TRUE(deckList.getCardList().isEmpty());
|
||||
}
|
||||
|
||||
void testHash(const QString &clipboard, const std::string &hash)
|
||||
{
|
||||
DeckList deckList = getDeckList(clipboard);
|
||||
|
||||
ASSERT_EQ(deckList.getDeckHash().toStdString(), hash);
|
||||
}
|
||||
|
||||
void testDeck(const QString &clipboard, const Result &result)
|
||||
{
|
||||
DeckList deckList = getDeckList(clipboard);
|
||||
|
||||
ASSERT_EQ(result.name, deckList.getName().toStdString());
|
||||
ASSERT_EQ(result.comments, deckList.getComments().toStdString());
|
||||
|
||||
CardRows mainboard;
|
||||
CardRows sideboard;
|
||||
|
||||
auto extractCards = [&mainboard, &sideboard](const InnerDecklistNode *innerDecklistNode,
|
||||
const DecklistCardNode *card) {
|
||||
if (innerDecklistNode->getName() == DECK_ZONE_MAIN) {
|
||||
mainboard.append({card->getName().toStdString(), card->getNumber()});
|
||||
} else if (innerDecklistNode->getName() == DECK_ZONE_SIDE) {
|
||||
sideboard.append({card->getName().toStdString(), card->getNumber()});
|
||||
} else {
|
||||
FAIL();
|
||||
}
|
||||
};
|
||||
|
||||
deckList.forEachCard(extractCards);
|
||||
|
||||
ASSERT_EQ(result.mainboard, mainboard);
|
||||
ASSERT_EQ(result.sideboard, sideboard);
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
#ifndef CLIPBOARD_TESTING_H
|
||||
#define CLIPBOARD_TESTING_H
|
||||
|
||||
#include "gtest/gtest.h"
|
||||
#include <libcockatrice/deck_list/deck_list.h>
|
||||
|
||||
// using std types because qt types aren't understood by gtest (without this you'll get less nice errors)
|
||||
using CardRows = QVector<std::pair<std::string, int>>;
|
||||
|
||||
struct Result
|
||||
{
|
||||
std::string name;
|
||||
std::string comments;
|
||||
CardRows mainboard;
|
||||
CardRows sideboard;
|
||||
|
||||
Result(std::string _name, std::string _comments, CardRows _mainboard, CardRows _sideboard)
|
||||
: name(_name), comments(_comments), mainboard(_mainboard), sideboard(_sideboard)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
void testEmpty(const QString &clipboard);
|
||||
void testHash(const QString &clipboard, const std::string &hash);
|
||||
void testDeck(const QString &clipboard, const Result &result);
|
||||
|
||||
#endif // CLIPBOARD_TESTING_H
|
||||
@@ -0,0 +1,226 @@
|
||||
#include "clipboard_testing.h"
|
||||
|
||||
// Testing is done by using the DeckList::loadFromString_Plain function in common/decklist.h
|
||||
// It does not check if cards are in the database at all, so no comparisons to the database will be made.
|
||||
|
||||
TEST(LoadingFromClipboardTest, EmptyDeck)
|
||||
{
|
||||
testEmpty("");
|
||||
}
|
||||
|
||||
TEST(LoadingFromClipboardTest, EmptySideboard)
|
||||
{
|
||||
testEmpty("Sideboard");
|
||||
}
|
||||
|
||||
TEST(LoadingFromClipboardTest, QuantityPrefixed)
|
||||
{
|
||||
QString clipboard("1 Mountain\n"
|
||||
"2x Island\n"
|
||||
"3x Forest\n");
|
||||
Result result("", "", {{"Mountain", 1}, {"Island", 2}, {"Forest", 3}}, {});
|
||||
testDeck(clipboard, result);
|
||||
}
|
||||
|
||||
TEST(LoadingFromClipboardTest, CommentsAreIgnored)
|
||||
{
|
||||
QString clipboard("//1 Mountain\n"
|
||||
"//2x Island\n"
|
||||
"//SB:2x Island\n");
|
||||
testEmpty(clipboard);
|
||||
}
|
||||
|
||||
TEST(LoadingFromClipboardTest, SideboardPrefix)
|
||||
{
|
||||
QString clipboard("1 Mountain\n"
|
||||
"SB: 1 Mountain\n"
|
||||
"sb: 2x Island\n"
|
||||
"2 Swamp\n"
|
||||
"\n"
|
||||
"3 Plains\n");
|
||||
Result result("", "", {{"Mountain", 1}, {"Swamp", 2}, {"Plains", 3}}, {{"Mountain", 1}, {"Island", 2}});
|
||||
testDeck(clipboard, result);
|
||||
}
|
||||
|
||||
TEST(LoadingFromClipboardTest, SideboardLine)
|
||||
{
|
||||
QString clipboard("1 Mountain\n"
|
||||
"2 Swamp\n"
|
||||
"\n"
|
||||
"3 Plains\n"
|
||||
"sideboard\n"
|
||||
"1 Mountain\n"
|
||||
"2x Island\n");
|
||||
Result result("", "", {{"Mountain", 1}, {"Swamp", 2}, {"Plains", 3}}, {{"Mountain", 1}, {"Island", 2}});
|
||||
testDeck(clipboard, result);
|
||||
}
|
||||
|
||||
TEST(LoadingFromClipboardTest, UnknownCardsAreNotDiscarded)
|
||||
{
|
||||
QString clipboard("1 CardThatDoesNotExistInCardsXml\n");
|
||||
Result result("", "", {{"CardThatDoesNotExistInCardsXml", 1}}, {});
|
||||
testDeck(clipboard, result);
|
||||
}
|
||||
|
||||
TEST(LoadingFromClipboardTest, WeirdWhitespaceIsIgnored)
|
||||
{
|
||||
QString clipboard(
|
||||
"\t\tSb:\t1\tOur Market Research Shows That Players Like Really Long Card Names So We Made "
|
||||
" This Card to Have\tthe Absolute \t Longest Card Name \tEver Elemental\t\n\t");
|
||||
Result result("", "", {},
|
||||
{{"Our Market Research Shows That Players Like Really Long Card Names So We Made This Card to Have "
|
||||
"the Absolute Longest Card Name Ever Elemental",
|
||||
1}});
|
||||
testDeck(clipboard, result);
|
||||
}
|
||||
|
||||
TEST(LoadingFromClipboardTest, RemoveBlankEntriesFromBeginningAndEnd)
|
||||
{
|
||||
QString clipboard("\n"
|
||||
"\n"
|
||||
"\n"
|
||||
"1x Algae Gharial\n"
|
||||
"3x CardThatDoesNotExistInCardsXml\n"
|
||||
"2x Phelddagrif\n"
|
||||
"\n"
|
||||
"\n");
|
||||
|
||||
Result result("", "", {{"Algae Gharial", 1}, {"CardThatDoesNotExistInCardsXml", 3}, {"Phelddagrif", 2}}, {});
|
||||
testDeck(clipboard, result);
|
||||
}
|
||||
|
||||
TEST(LoadingFromClipboardTest, UseFirstBlankIfOnlyOneBlankToSplitSideboard)
|
||||
{
|
||||
QString clipboard("1x Algae Gharial\n"
|
||||
"3x CardThatDoesNotExistInCardsXml\n"
|
||||
"\n"
|
||||
"2x Phelddagrif\n");
|
||||
|
||||
Result result("", "", {{"Algae Gharial", 1}, {"CardThatDoesNotExistInCardsXml", 3}}, {{"Phelddagrif", 2}});
|
||||
testDeck(clipboard, result);
|
||||
}
|
||||
|
||||
TEST(LoadingFromClipboardTest, IfMultipleScatteredBlanksAllMainBoard)
|
||||
{
|
||||
QString clipboard("1x Algae Gharial\n"
|
||||
"3x CardThatDoesNotExistInCardsXml\n"
|
||||
"\n"
|
||||
"2x Phelddagrif\n"
|
||||
"\n"
|
||||
"3 Giant Growth\n");
|
||||
|
||||
Result result(
|
||||
"", "", {{"Algae Gharial", 1}, {"CardThatDoesNotExistInCardsXml", 3}, {"Phelddagrif", 2}, {"Giant Growth", 3}},
|
||||
{});
|
||||
testDeck(clipboard, result);
|
||||
}
|
||||
|
||||
TEST(LoadingFromClipboardTest, EdgeCaseTesting)
|
||||
{
|
||||
QString clipboard(R"(
|
||||
// DeckName
|
||||
|
||||
// Comment 1
|
||||
|
||||
//
|
||||
//Comment [two]
|
||||
//(test) Æ ’ | / (3)
|
||||
|
||||
|
||||
// Mainboard (11 cards)
|
||||
Æther Adept
|
||||
2x Fire // Ice
|
||||
1 Minsc & Boo, Timeless Heroes
|
||||
3 Pain/Suffering
|
||||
4X [B] Forest (3)
|
||||
|
||||
|
||||
// Sideboard (11 cards)
|
||||
|
||||
5x [WTH] Nature’s Resurgence
|
||||
6X Gaea's Skyfolk
|
||||
7 B.F.M. (Big Furry Monster)
|
||||
|
||||
|
||||
|
||||
)");
|
||||
|
||||
Result result("DeckName", "Comment 1\n\nComment [two]\n(test) Æ ’ | / (3)",
|
||||
{{"Aether Adept", 1},
|
||||
{"Fire // Ice", 2},
|
||||
{"Minsc & Boo, Timeless Heroes", 1},
|
||||
{"Pain // Suffering", 3},
|
||||
{"Forest", 4}},
|
||||
{{"Nature's Resurgence", 5}, {"Gaea's Skyfolk", 6}, {"B.F.M. (Big Furry Monster)", 7}});
|
||||
testDeck(clipboard, result);
|
||||
}
|
||||
|
||||
TEST(LoadingFromClipboardTest, CommentsBeforeCardsTesting)
|
||||
{
|
||||
QString clipboard("// Title from website.com\n"
|
||||
"// A nice deck\n"
|
||||
"// With nice cards\n"
|
||||
"\n"
|
||||
"// Mainboard\n"
|
||||
"1 test1\n"
|
||||
"Sideboard\n"
|
||||
"2 test2\n");
|
||||
|
||||
Result result("Title from website.com", "A nice deck\nWith nice cards", {{"test1", 1}}, {{"test2", 2}});
|
||||
testDeck(clipboard, result);
|
||||
}
|
||||
|
||||
TEST(LoadingFromClipboardTest, mainboardAsLine)
|
||||
{
|
||||
QString clipboard("// Deck Name\n"
|
||||
"\n"
|
||||
"MainBoard: 3 cards\n"
|
||||
"3 card\n"
|
||||
"\n"
|
||||
"SideBoard: 2 cards\n"
|
||||
"2 sidecard\n");
|
||||
|
||||
Result result("Deck Name", "", {{"card", 3}}, {{"sidecard", 2}});
|
||||
testDeck(clipboard, result);
|
||||
}
|
||||
|
||||
TEST(LoadingFromClipboardTest, deckAsCard)
|
||||
{
|
||||
QString clipboard("6 Deck of Cards But Animated\n"
|
||||
"\n"
|
||||
"7 Sideboard Card\n");
|
||||
|
||||
Result result("", "", {{"Deck of Cards But Animated", 6}}, {{"Sideboard Card", 7}});
|
||||
testDeck(clipboard, result);
|
||||
}
|
||||
|
||||
TEST(LoadingFromClipboardTest, emptyMainBoard)
|
||||
{
|
||||
QString clipboard("deck\n"
|
||||
"\n"
|
||||
"sideboard\n");
|
||||
|
||||
testEmpty(clipboard);
|
||||
}
|
||||
|
||||
TEST(LoadingFromClipboardTest, emptyHash)
|
||||
{
|
||||
QString clipboard("");
|
||||
|
||||
testHash(clipboard, "r8sq7riu");
|
||||
}
|
||||
|
||||
TEST(LoadingFromClipboardTest, deckHash)
|
||||
{
|
||||
QString clipboard("1 Mountain\n"
|
||||
"2 Island\n"
|
||||
"SB: 3 Forest\n");
|
||||
|
||||
testHash(clipboard, "5cac19qm");
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
::testing::InitGoogleTest(&argc, argv);
|
||||
return RUN_ALL_TESTS();
|
||||
}
|
||||
Executable
+16
@@ -0,0 +1,16 @@
|
||||
add_executable(reverse_card_move_test reverse_card_move_test.cpp)
|
||||
|
||||
if(NOT GTEST_FOUND)
|
||||
add_dependencies(reverse_card_move_test gtest)
|
||||
endif()
|
||||
|
||||
target_link_libraries(
|
||||
reverse_card_move_test
|
||||
PRIVATE libcockatrice_network_server_remote
|
||||
PRIVATE libcockatrice_rng
|
||||
PRIVATE Threads::Threads
|
||||
PRIVATE ${GTEST_BOTH_LIBRARIES}
|
||||
PRIVATE ${TEST_QT_MODULES}
|
||||
)
|
||||
|
||||
add_test(NAME reverse_card_move_test COMMAND reverse_card_move_test)
|
||||
@@ -0,0 +1,91 @@
|
||||
#include "game/server_abstract_player.h"
|
||||
#include "game/server_card.h"
|
||||
#include "game/server_cardzone.h"
|
||||
#include "game/server_game.h"
|
||||
#include "server_response_containers.h"
|
||||
#include "server_room.h"
|
||||
#include "server_test_helpers.h"
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
#include <libcockatrice/protocol/pb/command_move_card.pb.h>
|
||||
#include <libcockatrice/protocol/pb/serverinfo_user.pb.h>
|
||||
#include <libcockatrice/rng/rng_abstract.h>
|
||||
#include <libcockatrice/utility/zone_names.h>
|
||||
|
||||
RNG_Abstract *rng = nullptr; // this needs to be defined due to other functions in server
|
||||
|
||||
TEST(ReverseCardMoveTest, MoveCardFromBottomTest)
|
||||
{
|
||||
ServerInfo_User user;
|
||||
user.set_name("test-user");
|
||||
|
||||
// instantiate a fake server instance
|
||||
FakeServer server;
|
||||
Server_Room room(0, 0, "", "", "", "", false, "", {}, &server);
|
||||
Server_Game game(user, 1, "", "", 2, QList<int>(), false, false, false, false, false, false, 20, false, &room);
|
||||
Server_AbstractPlayer player(&game, 1, user, false, nullptr);
|
||||
Server_CardZone deckZone(&player, ZoneNames::DECK, true, ServerInfo_Zone::PublicZone);
|
||||
Server_CardZone exileZone(&player, ZoneNames::EXILE, true, ServerInfo_Zone::PublicZone);
|
||||
|
||||
// setup the deck with 20 useless cards
|
||||
for (int i = 0; i < 20; i++) {
|
||||
auto *cardUseless = new Server_Card({"Card Useless", "card-Useless"}, player.newCardId(), i, 0);
|
||||
deckZone.insertCard(cardUseless, i, 0);
|
||||
}
|
||||
|
||||
// add 4 cards to the end of it
|
||||
auto *cardA = new Server_Card({"Card A", "card-a"}, player.newCardId(), 20, 0);
|
||||
auto *cardB = new Server_Card({"Card B", "card-b"}, player.newCardId(), 21, 0);
|
||||
auto *cardC = new Server_Card({"Card C", "card-c"}, player.newCardId(), 22, 0);
|
||||
auto *cardD = new Server_Card({"Card D", "card-d"}, player.newCardId(), 23, 0);
|
||||
|
||||
deckZone.insertCard(cardA, 20, 0);
|
||||
deckZone.insertCard(cardB, 21, 0);
|
||||
deckZone.insertCard(cardC, 22, 0);
|
||||
deckZone.insertCard(cardD, 23, 0);
|
||||
|
||||
// try to move them, with the expected client given order (n-3, n-2, n-1, n)
|
||||
CardToMove moveA;
|
||||
moveA.set_card_id(cardA->getId());
|
||||
CardToMove moveB;
|
||||
moveB.set_card_id(cardB->getId());
|
||||
CardToMove moveC;
|
||||
moveC.set_card_id(cardC->getId());
|
||||
CardToMove moveD;
|
||||
moveD.set_card_id(cardD->getId());
|
||||
|
||||
QList<const CardToMove *> cardsToMove = {&moveA, &moveB, &moveC, &moveD};
|
||||
GameEventStorage ges;
|
||||
|
||||
const auto response = player.moveCard(ges, &deckZone, cardsToMove, &exileZone, 0, 0, false, false, false);
|
||||
|
||||
EXPECT_EQ(response, Response::RespOk);
|
||||
|
||||
int positionA;
|
||||
int positionB;
|
||||
int positionC;
|
||||
int positionD;
|
||||
// find the cards in the destination zone and check they are the right card
|
||||
EXPECT_EQ(exileZone.getCard(cardA->getId(), &positionA), cardA);
|
||||
EXPECT_EQ(exileZone.getCard(cardB->getId(), &positionB), cardB);
|
||||
EXPECT_EQ(exileZone.getCard(cardC->getId(), &positionC), cardC);
|
||||
EXPECT_EQ(exileZone.getCard(cardD->getId(), &positionD), cardD);
|
||||
|
||||
// check that they are at the expected index
|
||||
EXPECT_EQ(cardA->getX(), 3);
|
||||
EXPECT_EQ(cardB->getX(), 2);
|
||||
EXPECT_EQ(cardC->getX(), 1);
|
||||
EXPECT_EQ(cardD->getX(), 0);
|
||||
|
||||
// also check if the given positions are correct
|
||||
EXPECT_EQ(positionA, 3);
|
||||
EXPECT_EQ(positionB, 2);
|
||||
EXPECT_EQ(positionC, 1);
|
||||
EXPECT_EQ(positionD, 0);
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
::testing::InitGoogleTest(&argc, argv);
|
||||
return RUN_ALL_TESTS();
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
#include "server.h"
|
||||
#include "server_database_interface.h"
|
||||
|
||||
class MockDatabaseInterface : public Server_DatabaseInterface
|
||||
{
|
||||
public:
|
||||
AuthenticationResult checkUserPassword(Server_ProtocolHandler *,
|
||||
const QString &,
|
||||
const QString &,
|
||||
const QString &,
|
||||
QString &,
|
||||
int &,
|
||||
bool) override
|
||||
{
|
||||
return NotLoggedIn;
|
||||
}
|
||||
ServerInfo_User getUserData(const QString &, bool) override
|
||||
{
|
||||
return ServerInfo_User();
|
||||
}
|
||||
int getNextGameId() override
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
int getNextReplayId() override
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
int getActiveUserCount(QString) override
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
};
|
||||
|
||||
class FakeServer : public Server
|
||||
{
|
||||
public:
|
||||
FakeServer()
|
||||
{
|
||||
setDatabaseInterface(new MockDatabaseInterface());
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,9 @@
|
||||
add_executable(parse_cipt_test ../../oracle/src/parsehelpers.cpp parse_cipt_test.cpp)
|
||||
|
||||
if(NOT GTEST_FOUND)
|
||||
add_dependencies(parse_cipt_test gtest)
|
||||
endif()
|
||||
|
||||
target_link_libraries(parse_cipt_test Threads::Threads ${GTEST_BOTH_LIBRARIES} ${TEST_QT_MODULES})
|
||||
|
||||
add_test(NAME parse_cipt_test COMMAND parse_cipt_test)
|
||||
@@ -0,0 +1,219 @@
|
||||
#include "../../oracle/src/parsehelpers.h"
|
||||
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
TEST(ParseCiptTest, parsesThisEntersTapped)
|
||||
{
|
||||
auto name = "Boring Fields";
|
||||
auto text = "This land enters tapped.";
|
||||
|
||||
ASSERT_TRUE(parseCipt(name, text));
|
||||
}
|
||||
|
||||
TEST(ParseCiptTest, parsesThisEntersTheBattlefieldTapped)
|
||||
{
|
||||
auto name = "Boring Fields";
|
||||
auto text = "This land enters the battlefield tapped.\n"
|
||||
"{T}: Add {G}.";
|
||||
|
||||
ASSERT_TRUE(parseCipt(name, text));
|
||||
}
|
||||
|
||||
TEST(ParseCiptTest, parsesItEntersTappedAtEndOfSentence)
|
||||
{
|
||||
auto name = "Shocking Fields";
|
||||
auto text = "As this land enters, you may pay 2 life. If you don't, it enters tapped.\n"
|
||||
"{T}: Add {G}.";
|
||||
|
||||
ASSERT_TRUE(parseCipt(name, text));
|
||||
}
|
||||
|
||||
TEST(ParseCiptTest, parsesThisEntersTappedWhenNotOnFirstLine)
|
||||
{
|
||||
auto name = "Boring Fields";
|
||||
auto text = "Flying\n"
|
||||
"This land enters tapped.\n"
|
||||
"{T}: Add {G}.";
|
||||
|
||||
ASSERT_TRUE(parseCipt(name, text));
|
||||
}
|
||||
|
||||
TEST(ParseCiptTest, parsesFullNameWithUnderscoreAppendedText)
|
||||
{
|
||||
auto name = "Boring Fields_SL50";
|
||||
auto text = "Boring Fields enters tapped.\n"
|
||||
"{T}: Add {G}.";
|
||||
|
||||
ASSERT_TRUE(parseCipt(name, text));
|
||||
}
|
||||
|
||||
TEST(ParseCiptTest, parsesFullNameWithBracketsAppendedText)
|
||||
{
|
||||
auto name = "Boring Fields (SL50)";
|
||||
auto text = "Boring Fields enters tapped.\n"
|
||||
"{T}: Add {G}.";
|
||||
|
||||
ASSERT_TRUE(parseCipt(name, text));
|
||||
}
|
||||
|
||||
TEST(ParseCiptTest, parsesFullNameWithComma)
|
||||
{
|
||||
auto name = "Bob, the Legend";
|
||||
auto text = "Bob, the Legend enters tapped.\n"
|
||||
"Whenever Bob attacks, you win the game.";
|
||||
|
||||
ASSERT_TRUE(parseCipt(name, text));
|
||||
}
|
||||
|
||||
TEST(ParseCiptTest, parsesFullNameWithCommaAtEndOfSentence)
|
||||
{
|
||||
auto name = "Bob, the Legend";
|
||||
auto text = "As Bob, the Legend enters, you may pay 2 life. If you don't, Bob, the Legend enters tapped.\n"
|
||||
"Whenever Bob attacks, you win the game.";
|
||||
|
||||
ASSERT_TRUE(parseCipt(name, text));
|
||||
}
|
||||
|
||||
TEST(ParseCiptTest, parsesFullNameWithApostropheAtEndOfSentence)
|
||||
{
|
||||
auto name = "Bob's Bobber";
|
||||
auto text = "As Bob's Bobber enters, you may pay 2 life. If you don't, Bob's Bobber enters tapped.\n"
|
||||
"Whenever Bob attacks, you win the game.";
|
||||
|
||||
ASSERT_TRUE(parseCipt(name, text));
|
||||
}
|
||||
|
||||
TEST(ParseCiptTest, parsesShortnameEndingWithComma)
|
||||
{
|
||||
auto name = "Bob, the Legend";
|
||||
auto text = "Bob enters tapped.\n"
|
||||
"Whenever Bob attacks, you win the game.";
|
||||
|
||||
ASSERT_TRUE(parseCipt(name, text));
|
||||
}
|
||||
|
||||
TEST(ParseCiptTest, parsesShortnameEndingWithSpace)
|
||||
{
|
||||
auto name = "Bob the Legend";
|
||||
auto text = "Bob enters tapped.\n"
|
||||
"Whenever Bob attacks, you win the game.";
|
||||
|
||||
ASSERT_TRUE(parseCipt(name, text));
|
||||
}
|
||||
|
||||
TEST(ParseCiptTest, parsesMultiWordShortnameEndingWithComma)
|
||||
{
|
||||
auto name = "Bob Dod, the Legend";
|
||||
auto text = "Bob Dod enters tapped.\n"
|
||||
"Whenever Bob Dod attacks, you win the game.";
|
||||
|
||||
ASSERT_TRUE(parseCipt(name, text));
|
||||
}
|
||||
|
||||
TEST(ParseCiptTest, parsesMultiWordShortnameEndingWithSpace)
|
||||
{
|
||||
auto name = "Bob Dod the Legend";
|
||||
auto text = "Bob Dod enters tapped.\n"
|
||||
"Whenever Bob Dod attacks, you win the game.";
|
||||
|
||||
ASSERT_TRUE(parseCipt(name, text));
|
||||
}
|
||||
|
||||
TEST(ParseCiptTest, parsesShortnameEndingWithSpaceWithUnderscoreAppendedText)
|
||||
{
|
||||
auto name = "Bob the Legend_SL50";
|
||||
auto text = "Bob enters tapped.\n"
|
||||
"Whenever Bob attacks, you win the game.";
|
||||
|
||||
ASSERT_TRUE(parseCipt(name, text));
|
||||
}
|
||||
|
||||
TEST(ParseCiptTest, parsesShortnameEndingWithSpaceWithBracketsAppendedText)
|
||||
{
|
||||
auto name = "Bob the Legend (SL50)";
|
||||
auto text = "Bob enters tapped.\n"
|
||||
"Whenever Bob attacks, you win the game.";
|
||||
|
||||
ASSERT_TRUE(parseCipt(name, text));
|
||||
}
|
||||
|
||||
TEST(ParseCiptTest, parsesMultiWordShortnameEndingWithSpaceWithUnderscoreAppendedText)
|
||||
{
|
||||
auto name = "Bob Dod the Legend_SL50";
|
||||
auto text = "Bob Dod enters tapped.\n"
|
||||
"Whenever Bob Dod attacks, you win the game.";
|
||||
|
||||
ASSERT_TRUE(parseCipt(name, text));
|
||||
}
|
||||
|
||||
TEST(ParseCiptTest, parsesMultiWordShortnameEndingWithSpaceWithBracketsAppendedText)
|
||||
{
|
||||
auto name = "Bob Dod the Legend (SL50)";
|
||||
auto text = "Bob Dod enters tapped.\n"
|
||||
"Whenever Bob Dod attacks, you win the game.";
|
||||
|
||||
ASSERT_TRUE(parseCipt(name, text));
|
||||
}
|
||||
|
||||
TEST(ParseCiptTest, rejectsEmptyText)
|
||||
{
|
||||
auto name = "Vanilla Dude";
|
||||
auto text = "";
|
||||
|
||||
ASSERT_FALSE(parseCipt(name, text));
|
||||
}
|
||||
|
||||
TEST(ParseCiptTest, rejectsEntersTappedUnless)
|
||||
{
|
||||
auto name = "Fast Fields";
|
||||
auto text = "This land enters tapped unless you control another land.";
|
||||
|
||||
ASSERT_FALSE(parseCipt(name, text));
|
||||
}
|
||||
|
||||
TEST(ParseCiptTest, rejectsWhenNameIsDifferent)
|
||||
{
|
||||
auto name = "Boring Fields";
|
||||
auto text = "Fast Fields enters tapped.";
|
||||
|
||||
ASSERT_FALSE(parseCipt(name, text));
|
||||
}
|
||||
|
||||
TEST(ParseCiptTest, rejectsOtherCreaturesEnterTapped)
|
||||
{
|
||||
auto name = "Imposing Guy";
|
||||
auto text = "Other creatures enter tapped.";
|
||||
|
||||
ASSERT_FALSE(parseCipt(name, text));
|
||||
}
|
||||
|
||||
TEST(ParseCiptTest, rejectsAbilityGrantingEntersTapped)
|
||||
{
|
||||
auto name = "Imposing Guy";
|
||||
auto text = "Other creatures have \"This creature enters tapped\".";
|
||||
|
||||
ASSERT_FALSE(parseCipt(name, text));
|
||||
}
|
||||
|
||||
TEST(ParseCiptTest, parsesEntersTappedAndAbilityGrantingEntersTappedOnSameCard)
|
||||
{
|
||||
auto name = "Imposing Guy";
|
||||
auto text = "This creature enters tapped."
|
||||
"Other creatures have \"This creature enters tapped\".";
|
||||
|
||||
ASSERT_TRUE(parseCipt(name, text));
|
||||
}
|
||||
|
||||
TEST(ParseCiptTest, rejectsItEntersTappedAndAttacking)
|
||||
{
|
||||
auto name = "Token Maker";
|
||||
auto text = "When Token Maker attacks, create a token. It enters tapped and attacking.";
|
||||
|
||||
ASSERT_FALSE(parseCipt(name, text));
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
::testing::InitGoogleTest(&argc, argv);
|
||||
return RUN_ALL_TESTS();
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
#include "gtest/gtest.h"
|
||||
#include <libcockatrice/rng/rng_abstract.h>
|
||||
#include <libcockatrice/rng/rng_sfmt.h>
|
||||
#include <libcockatrice/utility/passwordhasher.h>
|
||||
|
||||
RNG_Abstract *rng;
|
||||
|
||||
namespace
|
||||
{
|
||||
class PasswordHashTest : public ::testing::Test
|
||||
{
|
||||
protected:
|
||||
void SetUp() override
|
||||
{
|
||||
rng = new RNG_SFMT;
|
||||
}
|
||||
|
||||
void TearDown() override
|
||||
{
|
||||
delete rng;
|
||||
}
|
||||
};
|
||||
|
||||
TEST(PasswordHashTest, RegressionTest)
|
||||
{
|
||||
QString salt = "saltsaltsaltsalt";
|
||||
QString password = "password";
|
||||
QString expected = "vmKoWv975yf+WT2QCXhW48JNzZ2ghGxdgNvuKLBU0h7s6AQHSG72J6QO4ZswuSeqvBbAXbmgJSRBaSJrgc55WA==";
|
||||
QString hash = PasswordHasher::computeHash(password, salt);
|
||||
ASSERT_EQ(hash, salt + expected) << "The computed hash value remains the same";
|
||||
}
|
||||
} // namespace
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
::testing::InitGoogleTest(&argc, argv);
|
||||
return RUN_ALL_TESTS();
|
||||
}
|
||||
@@ -0,0 +1,183 @@
|
||||
/** @file server_card_counter_test.cpp
|
||||
* @brief Tests for Server_Card counter operations.
|
||||
* @ingroup Tests
|
||||
*/
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
#include <libcockatrice/network/server/remote/game/server_card.h>
|
||||
#include <libcockatrice/protocol/pb/event_set_card_counter.pb.h>
|
||||
#include <libcockatrice/utility/card_ref.h>
|
||||
#include <libcockatrice/utility/counter_limits.h>
|
||||
#include <limits>
|
||||
|
||||
TEST(ServerCardCounter, IncrementNewCounter)
|
||||
{
|
||||
Server_Card card(CardRef{"TestCard", ""}, 1, 0, 0);
|
||||
EXPECT_TRUE(card.incrementCounter(1, 10));
|
||||
EXPECT_EQ(card.getCounter(1), 10);
|
||||
}
|
||||
|
||||
TEST(ServerCardCounter, IncrementExistingCounter)
|
||||
{
|
||||
Server_Card card(CardRef{"TestCard", ""}, 1, 0, 0);
|
||||
ASSERT_TRUE(card.setCounter(1, 50));
|
||||
EXPECT_TRUE(card.incrementCounter(1, 10));
|
||||
EXPECT_EQ(card.getCounter(1), 60);
|
||||
}
|
||||
|
||||
TEST(ServerCardCounter, IncrementOverflowProtection)
|
||||
{
|
||||
Server_Card card(CardRef{"TestCard", ""}, 1, 0, 0);
|
||||
ASSERT_TRUE(card.setCounter(1, MAX_COUNTER_VALUE));
|
||||
EXPECT_FALSE(card.incrementCounter(1, 1));
|
||||
EXPECT_EQ(card.getCounter(1), MAX_COUNTER_VALUE);
|
||||
}
|
||||
|
||||
TEST(ServerCardCounter, DecrementUnderflowProtection)
|
||||
{
|
||||
Server_Card card(CardRef{"TestCard", ""}, 1, 0, 0);
|
||||
ASSERT_TRUE(card.setCounter(1, 5));
|
||||
EXPECT_TRUE(card.incrementCounter(1, -10));
|
||||
EXPECT_EQ(card.getCounter(1), 0);
|
||||
EXPECT_FALSE(card.getCounters().contains(1));
|
||||
}
|
||||
|
||||
TEST(ServerCardCounter, ReturnsFalseWhenUnchanged)
|
||||
{
|
||||
Server_Card card(CardRef{"TestCard", ""}, 1, 0, 0);
|
||||
ASSERT_TRUE(card.setCounter(1, 50));
|
||||
EXPECT_FALSE(card.incrementCounter(1, 0));
|
||||
EXPECT_EQ(card.getCounter(1), 50);
|
||||
}
|
||||
|
||||
TEST(ServerCardCounter, DecrementToZeroRemovesCounter)
|
||||
{
|
||||
Server_Card card(CardRef{"TestCard", ""}, 1, 0, 0);
|
||||
ASSERT_TRUE(card.setCounter(1, 10));
|
||||
EXPECT_TRUE(card.incrementCounter(1, -10));
|
||||
EXPECT_EQ(card.getCounter(1), 0);
|
||||
EXPECT_FALSE(card.getCounters().contains(1));
|
||||
}
|
||||
|
||||
TEST(ServerCardCounter, SetToZeroRemovesCounter)
|
||||
{
|
||||
Server_Card card(CardRef{"TestCard", ""}, 1, 0, 0);
|
||||
ASSERT_TRUE(card.setCounter(1, 10));
|
||||
EXPECT_TRUE(card.setCounter(1, 0));
|
||||
EXPECT_EQ(card.getCounter(1), 0);
|
||||
EXPECT_FALSE(card.getCounters().contains(1));
|
||||
}
|
||||
|
||||
TEST(ServerCardCounter, SetCounterReturnsFalseWhenUnchanged)
|
||||
{
|
||||
Server_Card card(CardRef{"TestCard", ""}, 1, 0, 0);
|
||||
ASSERT_TRUE(card.setCounter(1, 50));
|
||||
EXPECT_FALSE(card.setCounter(1, 50));
|
||||
EXPECT_EQ(card.getCounter(1), 50);
|
||||
}
|
||||
|
||||
TEST(ServerCardCounter, SetCounterReturnsTrueWhenChanged)
|
||||
{
|
||||
Server_Card card(CardRef{"TestCard", ""}, 1, 0, 0);
|
||||
ASSERT_TRUE(card.setCounter(1, 50));
|
||||
EXPECT_TRUE(card.setCounter(1, 100));
|
||||
EXPECT_EQ(card.getCounter(1), 100);
|
||||
}
|
||||
|
||||
TEST(ServerCardCounter, SetCounterEventNotPopulatedWhenUnchanged)
|
||||
{
|
||||
Server_Card card(CardRef{"TestCard", ""}, 1, 0, 0);
|
||||
ASSERT_TRUE(card.setCounter(1, 50));
|
||||
|
||||
Event_SetCardCounter event;
|
||||
event.set_counter_id(999);
|
||||
event.set_counter_value(999);
|
||||
|
||||
EXPECT_FALSE(card.setCounter(1, 50, &event));
|
||||
EXPECT_EQ(event.counter_id(), 999);
|
||||
EXPECT_EQ(event.counter_value(), 999);
|
||||
}
|
||||
|
||||
TEST(ServerCardCounter, IncrementCounterPopulatesEvent)
|
||||
{
|
||||
Server_Card card(CardRef{"TestCard", ""}, 1, 0, 0);
|
||||
ASSERT_TRUE(card.setCounter(1, 50));
|
||||
|
||||
Event_SetCardCounter event;
|
||||
EXPECT_TRUE(card.incrementCounter(1, 10, &event));
|
||||
|
||||
EXPECT_EQ(event.counter_id(), 1);
|
||||
EXPECT_EQ(event.counter_value(), 60);
|
||||
}
|
||||
|
||||
TEST(ServerCardCounter, IncrementCounterEventReflectsClampedValue)
|
||||
{
|
||||
Server_Card card(CardRef{"TestCard", ""}, 1, 0, 0);
|
||||
ASSERT_TRUE(card.setCounter(1, MAX_COUNTER_VALUE - 5));
|
||||
|
||||
Event_SetCardCounter event;
|
||||
EXPECT_TRUE(card.incrementCounter(1, 10, &event));
|
||||
|
||||
EXPECT_EQ(event.counter_id(), 1);
|
||||
EXPECT_EQ(event.counter_value(), MAX_COUNTER_VALUE);
|
||||
}
|
||||
|
||||
TEST(ServerCardCounter, IncrementCounterNoEventWhenNullptr)
|
||||
{
|
||||
Server_Card card(CardRef{"TestCard", ""}, 1, 0, 0);
|
||||
ASSERT_TRUE(card.setCounter(1, 50));
|
||||
EXPECT_TRUE(card.incrementCounter(1, 10, nullptr));
|
||||
EXPECT_EQ(card.getCounter(1), 60);
|
||||
}
|
||||
|
||||
TEST(ServerCardCounter, IncrementCounterEventNotPopulatedWhenUnchanged)
|
||||
{
|
||||
Server_Card card(CardRef{"TestCard", ""}, 1, 0, 0);
|
||||
ASSERT_TRUE(card.setCounter(1, MAX_COUNTER_VALUE));
|
||||
|
||||
Event_SetCardCounter event;
|
||||
event.set_counter_id(999);
|
||||
event.set_counter_value(999);
|
||||
|
||||
EXPECT_FALSE(card.incrementCounter(1, 1, &event));
|
||||
EXPECT_EQ(event.counter_id(), 999);
|
||||
EXPECT_EQ(event.counter_value(), 999);
|
||||
}
|
||||
|
||||
TEST(ServerCardCounter, SetCounterClampsNegativeToZero)
|
||||
{
|
||||
Server_Card card(CardRef{"TestCard", ""}, 1, 0, 0);
|
||||
EXPECT_FALSE(card.setCounter(1, -5));
|
||||
EXPECT_EQ(card.getCounter(1), 0);
|
||||
EXPECT_FALSE(card.getCounters().contains(1));
|
||||
}
|
||||
|
||||
TEST(ServerCardCounter, SetCounterClampsAboveMaxToMax)
|
||||
{
|
||||
Server_Card card(CardRef{"TestCard", ""}, 1, 0, 0);
|
||||
EXPECT_TRUE(card.setCounter(1, 1500));
|
||||
EXPECT_EQ(card.getCounter(1), MAX_COUNTER_VALUE);
|
||||
}
|
||||
|
||||
TEST(ServerCardCounter, IncrementDoesNotGoBelowZero)
|
||||
{
|
||||
Server_Card card(CardRef{"TestCard", ""}, 1, 0, 0);
|
||||
ASSERT_TRUE(card.setCounter(1, 5));
|
||||
EXPECT_TRUE(card.incrementCounter(1, -10));
|
||||
EXPECT_EQ(card.getCounter(1), 0);
|
||||
EXPECT_FALSE(card.getCounters().contains(1));
|
||||
}
|
||||
|
||||
TEST(ServerCardCounter, IncrementDoesNotExceedMax)
|
||||
{
|
||||
Server_Card card(CardRef{"TestCard", ""}, 1, 0, 0);
|
||||
ASSERT_TRUE(card.setCounter(1, MAX_COUNTER_VALUE - 5));
|
||||
EXPECT_TRUE(card.incrementCounter(1, 10));
|
||||
EXPECT_EQ(card.getCounter(1), MAX_COUNTER_VALUE);
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
::testing::InitGoogleTest(&argc, argv);
|
||||
return RUN_ALL_TESTS();
|
||||
}
|
||||
@@ -0,0 +1,86 @@
|
||||
/** @file server_counter_test.cpp
|
||||
* @brief Tests for Server_Counter operations.
|
||||
* @ingroup Tests
|
||||
*/
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
#include <libcockatrice/network/server/remote/game/server_counter.h>
|
||||
#include <limits>
|
||||
|
||||
TEST(ServerCounter, IncrementDoesNotOverflow)
|
||||
{
|
||||
Server_Counter c(1, "test", color(), 10, std::numeric_limits<int>::max());
|
||||
bool changed = c.incrementCount(1);
|
||||
EXPECT_FALSE(changed);
|
||||
EXPECT_EQ(c.getCount(), std::numeric_limits<int>::max());
|
||||
}
|
||||
|
||||
TEST(ServerCounter, DecrementDoesNotUnderflow)
|
||||
{
|
||||
Server_Counter c(1, "test", color(), 10, std::numeric_limits<int>::min());
|
||||
bool changed = c.incrementCount(-1);
|
||||
EXPECT_FALSE(changed);
|
||||
EXPECT_EQ(c.getCount(), std::numeric_limits<int>::min());
|
||||
}
|
||||
|
||||
TEST(ServerCounter, SetCountReturnsFalseWhenUnchanged)
|
||||
{
|
||||
Server_Counter c(1, "test", color(), 10, 50);
|
||||
bool changed = c.setCount(50);
|
||||
EXPECT_FALSE(changed);
|
||||
}
|
||||
|
||||
TEST(ServerCounter, IncrementReturnsChangeStatus)
|
||||
{
|
||||
Server_Counter c(1, "test", color(), 10, 50);
|
||||
EXPECT_TRUE(c.incrementCount(10));
|
||||
EXPECT_EQ(c.getCount(), 60);
|
||||
EXPECT_FALSE(c.incrementCount(0));
|
||||
EXPECT_EQ(c.getCount(), 60);
|
||||
}
|
||||
|
||||
TEST(ServerCounter, LargePositiveDeltaDoesNotOverflow)
|
||||
{
|
||||
Server_Counter c(1, "test", color(), 10, std::numeric_limits<int>::max() - 10);
|
||||
bool changed = c.incrementCount(std::numeric_limits<int>::max());
|
||||
EXPECT_TRUE(changed); // Value changes from INT_MAX-10 to INT_MAX (clamped)
|
||||
EXPECT_EQ(c.getCount(), std::numeric_limits<int>::max());
|
||||
}
|
||||
|
||||
TEST(ServerCounter, LargeNegativeDeltaDoesNotUnderflow)
|
||||
{
|
||||
Server_Counter c(1, "test", color(), 10, std::numeric_limits<int>::min() + 10);
|
||||
bool changed = c.incrementCount(std::numeric_limits<int>::min());
|
||||
EXPECT_TRUE(changed); // Value changes from INT_MIN+10 to INT_MIN (clamped)
|
||||
EXPECT_EQ(c.getCount(), std::numeric_limits<int>::min());
|
||||
}
|
||||
|
||||
TEST(ServerCounter, SetCountReturnsTrueWhenChanged)
|
||||
{
|
||||
Server_Counter c(1, "test", color(), 10, 50);
|
||||
EXPECT_TRUE(c.setCount(100));
|
||||
EXPECT_EQ(c.getCount(), 100);
|
||||
}
|
||||
|
||||
TEST(ServerCounter, BasicIncrementWorks)
|
||||
{
|
||||
Server_Counter c(1, "test", color(), 10, 50);
|
||||
EXPECT_TRUE(c.incrementCount(10));
|
||||
EXPECT_EQ(c.getCount(), 60);
|
||||
EXPECT_TRUE(c.incrementCount(-20));
|
||||
EXPECT_EQ(c.getCount(), 40);
|
||||
}
|
||||
|
||||
TEST(ServerCounter, MixedExtremesDoNotClamp)
|
||||
{
|
||||
Server_Counter c(1, "test", color(), 10, std::numeric_limits<int>::max());
|
||||
bool changed = c.incrementCount(std::numeric_limits<int>::min());
|
||||
EXPECT_TRUE(changed);
|
||||
EXPECT_EQ(c.getCount(), -1);
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
::testing::InitGoogleTest(&argc, argv);
|
||||
return RUN_ALL_TESTS();
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
#include "gtest/gtest.h"
|
||||
#include <libcockatrice/utility/days_years_between.h>
|
||||
|
||||
namespace
|
||||
{
|
||||
using dayyear = QPair<int, int>;
|
||||
|
||||
TEST(AgeFormatting, Zero)
|
||||
{
|
||||
auto got = getDaysAndYearsBetween(QDate(2000, 1, 1), QDate(2000, 1, 1));
|
||||
ASSERT_EQ(got, dayyear(0, 0)) << "these are the same day";
|
||||
}
|
||||
|
||||
TEST(AgeFormatting, LeapDay)
|
||||
{
|
||||
auto got = getDaysAndYearsBetween(QDate(2000, 2, 28), QDate(2000, 3, 1));
|
||||
ASSERT_EQ(got, dayyear(2, 0)) << "there is a leap day in between these days";
|
||||
}
|
||||
|
||||
TEST(AgeFormatting, LeapYear)
|
||||
{
|
||||
auto got = getDaysAndYearsBetween(QDate(2000, 1, 1), QDate(2001, 1, 1));
|
||||
ASSERT_EQ(got, dayyear(0, 1)) << "there is a leap day in between these dates, but that's fine";
|
||||
}
|
||||
|
||||
TEST(AgeFormatting, LeapDayWithYear)
|
||||
{
|
||||
auto got = getDaysAndYearsBetween(QDate(2000, 2, 28), QDate(2001, 3, 1));
|
||||
ASSERT_EQ(got, dayyear(1, 1)) << "there is a leap day in between these days but not in the last year";
|
||||
}
|
||||
|
||||
TEST(AgeFormatting, LeapDayThisYear)
|
||||
{
|
||||
auto got = getDaysAndYearsBetween(QDate(2003, 2, 28), QDate(2004, 3, 1));
|
||||
ASSERT_EQ(got, dayyear(2, 1)) << "there is a leap day in between these days this year";
|
||||
}
|
||||
} // namespace
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
::testing::InitGoogleTest(&argc, argv);
|
||||
return RUN_ALL_TESTS();
|
||||
}
|
||||
Reference in New Issue
Block a user