1
0

Merge pull request #3228 from cuberite/SeparateSelfTests

Separate self tests
This commit is contained in:
Mattes D 2016-06-19 14:57:14 +02:00 committed by GitHub
commit 5ee6643804
42 changed files with 995 additions and 531 deletions

View File

@ -264,27 +264,6 @@ if (MSVC)
tolua
PROPERTIES FOLDER Support
)
if (${SELF_TEST})
set_target_properties(
Network
HTTP
PROPERTIES FOLDER Lib
)
set_target_properties(
arraystocoords-exe
ChunkBuffer
coordinates-exe
copies-exe
copyblocks-exe
creatable-exe
EchoServer
Google-exe
HTTPMessageParser_file-exe
LoadablePieces
NameLookup
PROPERTIES FOLDER Tests
)
endif()
if(${BUILD_TOOLS})
set_target_properties(

View File

@ -5,72 +5,6 @@
#include "Globals.h"
#include "BoundingBox.h"
#include "Defines.h"
#include "SelfTests.h"
#ifdef SELF_TEST
/** A simple self-test that is executed on program start, used to verify bbox functionality */
static class SelfTest_BoundingBox
{
public:
SelfTest_BoundingBox(void)
{
cSelfTests::Get().Register(cSelfTests::SelfTestFunction(&Test), "Bounding box intersections");
}
static void Test(void)
{
Vector3d Min(1, 1, 1);
Vector3d Max(2, 2, 2);
Vector3d LineDefs[] =
{
Vector3d(1.5, 4, 1.5), Vector3d(1.5, 3, 1.5), // Should intersect at 2, face 1 (YP)
Vector3d(1.5, 0, 1.5), Vector3d(1.5, 4, 1.5), // Should intersect at 0.25, face 0 (YM)
Vector3d(0, 0, 0), Vector3d(2, 2, 2), // Should intersect at 0.5, face 0, 3 or 5 (anyM)
Vector3d(0.999, 0, 1.5), Vector3d(0.999, 4, 1.5), // Should not intersect
Vector3d(1.999, 0, 1.5), Vector3d(1.999, 4, 1.5), // Should intersect at 0.25, face 0 (YM)
Vector3d(2.001, 0, 1.5), Vector3d(2.001, 4, 1.5), // Should not intersect
} ;
bool Results[] = {true, true, true, false, true, false};
double LineCoeffs[] = {2, 0.25, 0.5, 0, 0.25, 0};
for (size_t i = 0; i < ARRAYCOUNT(LineDefs) / 2; i++)
{
double LineCoeff;
eBlockFace Face;
Vector3d Line1 = LineDefs[2 * i];
Vector3d Line2 = LineDefs[2 * i + 1];
bool res = cBoundingBox::CalcLineIntersection(Min, Max, Line1, Line2, LineCoeff, Face);
if (res != Results[i])
{
LOGERROR("LineIntersection({%.02f, %.02f, %.02f}, {%.02f, %.02f, %.02f}) -> %d, %.05f, %d",
Line1.x, Line1.y, Line1.z,
Line2.x, Line2.y, Line2.z,
res ? 1 : 0, LineCoeff, Face
);
abort();
}
if (res)
{
if (LineCoeff != LineCoeffs[i])
{
LOGERROR("LineIntersection({%.02f, %.02f, %.02f}, {%.02f, %.02f, %.02f}) -> %d, %.05f, %d",
Line1.x, Line1.y, Line1.z,
Line2.x, Line2.y, Line2.z,
res ? 1 : 0, LineCoeff, Face
);
abort();
}
}
} // for i - LineDefs[]
}
} g_BoundingBoxTest;
#endif

View File

@ -8,7 +8,6 @@
#include "ByteBuffer.h"
#include "Endianness.h"
#include "OSSupport/IsThread.h"
#include "SelfTests.h"
@ -54,71 +53,6 @@ Unfortunately it is very slow, so it is disabled even for regular DEBUG builds.
#ifdef SELF_TEST
/** Self-test of the VarInt-reading and writing code */
static class cByteBufferSelfTest
{
public:
cByteBufferSelfTest(void)
{
cSelfTests::Get().Register(cSelfTests::SelfTestFunction(&TestRead), "ByteBuffer read");
cSelfTests::Get().Register(cSelfTests::SelfTestFunction(&TestWrite), "ByteBuffer write");
cSelfTests::Get().Register(cSelfTests::SelfTestFunction(&TestWrap), "ByteBuffer wraparound");
}
static void TestRead(void)
{
cByteBuffer buf(50);
buf.Write("\x05\xac\x02\x00", 4);
UInt32 v1;
assert_test(buf.ReadVarInt(v1) && (v1 == 5));
UInt32 v2;
assert_test(buf.ReadVarInt(v2) && (v2 == 300));
UInt32 v3;
assert_test(buf.ReadVarInt(v3) && (v3 == 0));
}
static void TestWrite(void)
{
cByteBuffer buf(50);
buf.WriteVarInt32(5);
buf.WriteVarInt32(300);
buf.WriteVarInt32(0);
AString All;
buf.ReadAll(All);
assert_test(All.size() == 4);
assert_test(memcmp(All.data(), "\x05\xac\x02\x00", All.size()) == 0);
}
static void TestWrap(void)
{
cByteBuffer buf(3);
for (int i = 0; i < 1000; i++)
{
size_t FreeSpace = buf.GetFreeSpace();
assert_test(buf.GetReadableSpace() == 0);
assert_test(FreeSpace > 0);
assert_test(buf.Write("a", 1));
assert_test(buf.CanReadBytes(1));
assert_test(buf.GetReadableSpace() == 1);
UInt8 v = 0;
assert_test(buf.ReadBEUInt8(v));
assert_test(v == 'a');
assert_test(buf.GetReadableSpace() == 0);
buf.CommitRead();
assert_test(buf.GetFreeSpace() == FreeSpace); // We're back to normal
}
}
} g_ByteBufferTest;
#endif
#ifdef DEBUG_SINGLE_THREAD_ACCESS
/** Simple RAII class that is used for checking that no two threads are using an object simultanously.

View File

@ -63,7 +63,6 @@ SET (SRCS
RCONServer.cpp
Root.cpp
Scoreboard.cpp
SelfTests.cpp
Server.cpp
SetChunkData.cpp
SpawnPrepare.cpp
@ -140,7 +139,6 @@ SET (HDRS
RCONServer.h
Root.h
Scoreboard.h
SelfTests.h
Server.h
SetChunkData.h
SettingsRepositoryInterface.h

View File

@ -6,95 +6,6 @@
#include "Globals.h"
#include "CompositeChat.h"
#include "ClientHandle.h"
#include "SelfTests.h"
#ifdef SELF_TEST
/** A simple self-test that verifies that the composite chat parser is working properly. */
class SelfTest_CompositeChat
{
public:
SelfTest_CompositeChat(void)
{
cSelfTests::Get().Register(cSelfTests::SelfTestFunction(&TestParser1), "CompositeChat parser test 1");
cSelfTests::Get().Register(cSelfTests::SelfTestFunction(&TestParser2), "CompositeChat parser test 2");
cSelfTests::Get().Register(cSelfTests::SelfTestFunction(&TestParser3), "CompositeChat parser test 3");
cSelfTests::Get().Register(cSelfTests::SelfTestFunction(&TestParser4), "CompositeChat parser test 4");
cSelfTests::Get().Register(cSelfTests::SelfTestFunction(&TestParser5), "CompositeChat parser test 5");
}
static void TestParser1(void)
{
cCompositeChat Msg;
Msg.ParseText("Testing @2color codes and http://links parser");
const cCompositeChat::cParts & Parts = Msg.GetParts();
assert_test(Parts.size() == 4);
assert_test(Parts[0]->m_PartType == cCompositeChat::ptText);
assert_test(Parts[1]->m_PartType == cCompositeChat::ptText);
assert_test(Parts[2]->m_PartType == cCompositeChat::ptUrl);
assert_test(Parts[3]->m_PartType == cCompositeChat::ptText);
assert_test(Parts[0]->m_Style == "");
assert_test(Parts[1]->m_Style == "@2");
assert_test(Parts[2]->m_Style == "@2");
assert_test(Parts[3]->m_Style == "@2");
}
static void TestParser2(void)
{
cCompositeChat Msg;
Msg.ParseText("@3Advanced stuff: @5overriding color codes and http://links.with/@4color-in-them handling");
const cCompositeChat::cParts & Parts = Msg.GetParts();
assert_test(Parts.size() == 4);
assert_test(Parts[0]->m_PartType == cCompositeChat::ptText);
assert_test(Parts[1]->m_PartType == cCompositeChat::ptText);
assert_test(Parts[2]->m_PartType == cCompositeChat::ptUrl);
assert_test(Parts[3]->m_PartType == cCompositeChat::ptText);
assert_test(Parts[0]->m_Style == "@3");
assert_test(Parts[1]->m_Style == "@5");
assert_test(Parts[2]->m_Style == "@5");
assert_test(Parts[3]->m_Style == "@5");
}
static void TestParser3(void)
{
cCompositeChat Msg;
Msg.ParseText("http://links.starting the text");
const cCompositeChat::cParts & Parts = Msg.GetParts();
assert_test(Parts.size() == 2);
assert_test(Parts[0]->m_PartType == cCompositeChat::ptUrl);
assert_test(Parts[1]->m_PartType == cCompositeChat::ptText);
assert_test(Parts[0]->m_Style == "");
assert_test(Parts[1]->m_Style == "");
}
static void TestParser4(void)
{
cCompositeChat Msg;
Msg.ParseText("links finishing the text: http://some.server");
const cCompositeChat::cParts & Parts = Msg.GetParts();
assert_test(Parts.size() == 2);
assert_test(Parts[0]->m_PartType == cCompositeChat::ptText);
assert_test(Parts[1]->m_PartType == cCompositeChat::ptUrl);
assert_test(Parts[0]->m_Style == "");
assert_test(Parts[1]->m_Style == "");
}
static void TestParser5(void)
{
cCompositeChat Msg;
Msg.ParseText("http://only.links");
const cCompositeChat::cParts & Parts = Msg.GetParts();
assert_test(Parts.size() == 1);
assert_test(Parts[0]->m_PartType == cCompositeChat::ptUrl);
assert_test(Parts[0]->m_Style == "");
}
} gTest;
#endif // SELF_TEST

View File

@ -6,7 +6,6 @@
#include "Globals.h"
#include "PieceGenerator.h"
#include "../SelfTests.h"
#include "VerticalStrategy.h"
#include "VerticalLimit.h"

View File

@ -6,7 +6,6 @@
#include "Globals.h"
#include "PrefabPiecePool.h"
#include "../Bindings/LuaState.h"
#include "SelfTests.h"
#include "WorldStorage/SchematicFileSerializer.h"
#include "VerticalStrategy.h"
#include "../StringCompression.h"

View File

@ -255,72 +255,73 @@ template class SizeChecker<UInt8, 1>;
#ifndef TEST_GLOBALS
// These fiunctions are defined in Logger.cpp, but are declared here to avoid including all of logger.h
extern void LOG (const char * a_Format, ...) FORMATSTRING(1, 2);
extern void LOGINFO (const char * a_Format, ...) FORMATSTRING(1, 2);
extern void LOGWARNING(const char * a_Format, ...) FORMATSTRING(1, 2);
extern void LOGERROR (const char * a_Format, ...) FORMATSTRING(1, 2);
// These functions are defined in Logger.cpp, but are declared here to avoid including all of logger.h
extern void LOG (const char * a_Format, ...) FORMATSTRING(1, 2);
extern void LOGINFO (const char * a_Format, ...) FORMATSTRING(1, 2);
extern void LOGWARNING(const char * a_Format, ...) FORMATSTRING(1, 2);
extern void LOGERROR (const char * a_Format, ...) FORMATSTRING(1, 2);
// In debug builds, translate LOGD to LOG, otherwise leave it out altogether:
#ifdef _DEBUG
#define LOGD LOG
#else
#define LOGD(...)
#endif // _DEBUG
#define LOGWARN LOGWARNING
// In debug builds, translate LOGD to LOG, otherwise leave it out altogether:
#ifdef _DEBUG
#define LOGD LOG
#else
#define LOGD(...)
#endif // _DEBUG
#define LOGWARN LOGWARNING
#else
// Logging functions
void inline LOGERROR(const char * a_Format, ...) FORMATSTRING(1, 2);
void inline LOGERROR(const char * a_Format, ...) FORMATSTRING(1, 2);
void inline LOGERROR(const char * a_Format, ...)
{
va_list argList;
va_start(argList, a_Format);
vprintf(a_Format, argList);
putchar('\n');
va_end(argList);
}
void inline LOGERROR(const char * a_Format, ...)
{
va_list argList;
va_start(argList, a_Format);
vprintf(a_Format, argList);
putchar('\n');
fflush(stdout);
va_end(argList);
}
void inline LOGWARNING(const char * a_Format, ...) FORMATSTRING(1, 2);
void inline LOGWARNING(const char * a_Format, ...) FORMATSTRING(1, 2);
void inline LOGWARNING(const char * a_Format, ...)
{
va_list argList;
va_start(argList, a_Format);
vprintf(a_Format, argList);
putchar('\n');
va_end(argList);
}
void inline LOGWARNING(const char * a_Format, ...)
{
va_list argList;
va_start(argList, a_Format);
vprintf(a_Format, argList);
putchar('\n');
fflush(stdout);
va_end(argList);
}
void inline LOGD(const char * a_Format, ...) FORMATSTRING(1, 2);
void inline LOGD(const char * a_Format, ...) FORMATSTRING(1, 2);
void inline LOGD(const char * a_Format, ...)
{
va_list argList;
va_start(argList, a_Format);
vprintf(a_Format, argList);
putchar('\n');
va_end(argList);
}
void inline LOGD(const char * a_Format, ...)
{
va_list argList;
va_start(argList, a_Format);
vprintf(a_Format, argList);
putchar('\n');
fflush(stdout);
va_end(argList);
}
void inline LOG(const char * a_Format, ...) FORMATSTRING(1, 2);
void inline LOG(const char * a_Format, ...) FORMATSTRING(1, 2);
void inline LOG(const char * a_Format, ...)
{
va_list argList;
va_start(argList, a_Format);
vprintf(a_Format, argList);
putchar('\n');
va_end(argList);
}
void inline LOG(const char * a_Format, ...)
{
va_list argList;
va_start(argList, a_Format);
vprintf(a_Format, argList);
putchar('\n');
fflush(stdout);
va_end(argList);
}
#define LOGINFO LOG
#define LOGWARN LOGWARNING
#define LOGINFO LOG
#define LOGWARN LOGWARNING
#endif

View File

@ -6,7 +6,6 @@
#include "Globals.h"
#include "Network.h"
#include "event2/util.h"
#include "../SelfTests.h"
#ifdef _WIN32
#include <IPHlpApi.h>
@ -22,34 +21,6 @@
#ifdef SELF_TEST
static class cEnumIPAddressTest
{
public:
cEnumIPAddressTest(void)
{
cSelfTests::Get().Register(std::function<void(void)>(&Test), "Network IP enumeration");
}
static void Test(void)
{
LOG("Enumerating all IP addresses...");
auto IPs = cNetwork::EnumLocalIPAddresses();
for (auto & ip: IPs)
{
LOG(" %s", ip.c_str());
}
LOG("Done.");
}
} g_EnumIPAddressTest;
#endif // SELF_TEST
#ifdef _WIN32
/** Converts the SOCKET_ADDRESS structure received from the OS into an IP address string. */

View File

@ -6,7 +6,6 @@
#include "Globals.h"
#include "NetworkSingleton.h"
#include <event2/event.h>
#include <event2/thread.h>
#include <event2/bufferevent.h>
#include <event2/dns.h>
@ -91,8 +90,11 @@ void cNetworkSingleton::Initialise(void)
}
// Create the event loop thread:
m_EventLoopThread = std::thread(RunEventLoop, this);
m_HasTerminated = false;
m_StartupEvent.reset(new cEvent);
m_EventLoopThread = std::thread(RunEventLoop, this);
m_StartupEvent->Wait(); // Wait for the LibEvent loop to actually start running (otherwise calling Terminate too soon would hang, see #3228)
m_StartupEvent.reset(); // Don't need the cEvent any more, release all its resources
}
@ -153,6 +155,9 @@ void cNetworkSingleton::LogCallback(int a_Severity, const char * a_Msg)
void cNetworkSingleton::RunEventLoop(cNetworkSingleton * a_Self)
{
auto timer = evtimer_new(a_Self->m_EventBase, SignalizeStartup, a_Self);
timeval timeout{}; // Zero timeout - execute immediately
evtimer_add(timer, &timeout);
event_base_loop(a_Self->m_EventBase, EVLOOP_NO_EXIT_ON_EMPTY);
}
@ -160,6 +165,18 @@ void cNetworkSingleton::RunEventLoop(cNetworkSingleton * a_Self)
void cNetworkSingleton::SignalizeStartup(evutil_socket_t a_Socket, short a_Events, void * a_Self)
{
auto self = reinterpret_cast<cNetworkSingleton *>(a_Self);
ASSERT(self != nullptr);
ASSERT(self->m_StartupEvent != nullptr);
self->m_StartupEvent->Set();
}
void cNetworkSingleton::AddHostnameLookup(cHostnameLookupPtr a_HostnameLookup)
{
ASSERT(!m_HasTerminated);

View File

@ -13,6 +13,7 @@
#pragma once
#include <event2/event.h>
#include "Network.h"
#include "CriticalSection.h"
#include "Event.h"
@ -127,11 +128,18 @@ protected:
/** The thread in which the main LibEvent loop runs. */
std::thread m_EventLoopThread;
/** Event that is signalled once the startup is finished and the LibEvent loop is running. */
UniquePtr<cEvent> m_StartupEvent;
/** Converts LibEvent-generated log events into log messages in MCS log. */
static void LogCallback(int a_Severity, const char * a_Msg);
/** Implements the thread that runs LibEvent's event dispatcher loop. */
static void RunEventLoop(cNetworkSingleton * a_Self);
/** Callback called by LibEvent when the event loop is started. */
static void SignalizeStartup(evutil_socket_t a_Socket, short a_Events, void * a_Self);
};

View File

@ -22,7 +22,6 @@
#include "IniFile.h"
#include "SettingsRepositoryInterface.h"
#include "OverridesSettingsRepository.h"
#include "SelfTests.h"
#include "Logger.h"
#include <iostream>
@ -128,11 +127,6 @@ void cRoot::Start(std::unique_ptr<cSettingsRepositoryInterface> a_OverridesRepo)
LOG("from commit id: " BUILD_COMMIT_ID " built at: " BUILD_DATETIME);
#endif
// Run the self-tests registered previously via cSelfTests::Register():
#ifdef SELF_TEST
cSelfTests::ExecuteAll();
#endif
cDeadlockDetect dd;
auto BeginTime = std::chrono::steady_clock::now();

View File

@ -1,71 +0,0 @@
// SelfTests.h
// Implements the cSelfTests class representing the singleton used for registering self-tests
// This class is only declared if SELF_TEST macro is defined.
#include "Globals.h"
#include "SelfTests.h"
#ifdef SELF_TEST
cSelfTests::cSelfTests(void):
m_AllowRegistering(true)
{
}
cSelfTests & cSelfTests::Get(void)
{
static cSelfTests singleton;
return singleton;
}
void cSelfTests::Register(cSelfTests::SelfTestFunction a_FnToExecute, const AString & a_TestName)
{
ASSERT(Get().m_AllowRegistering);
Get().m_SelfTests.push_back(std::make_pair(a_FnToExecute, a_TestName));
}
void cSelfTests::ExecuteAll(void)
{
Get().m_AllowRegistering = false;
LOG("--- Performing self-tests ---");
for (auto & test: Get().m_SelfTests)
{
LOG("Performing self-test: %s", test.second.c_str());
try
{
test.first();
}
catch (const std::exception & exc)
{
LOGWARNING("Exception in test %s: %s", test.second.c_str(), exc.what());
}
catch (...)
{
LOGWARNING("Unknown exception in test %s", test.second.c_str());
}
} // for test - m_SelfTests[]
LOG("--- Self-tests finished ---");
}
#endif // SELF_TEST

View File

@ -1,51 +0,0 @@
// SelfTests.h
// Declares the cSelfTests class representing the singleton used for registering self-tests
// This class is only declared if SELF_TEST macro is defined.
#pragma once
#ifdef SELF_TEST
/** Singleton containing registered self-tests.
Used to schedule self-tests to run after the logging framework is initialized (#2228). */
class cSelfTests
{
public:
/** Returns the singleton instance of this class. */
static cSelfTests & Get(void);
// typedef void (* SelfTestFunction)(void);
typedef std::function<void(void)> SelfTestFunction;
/** Registers a self-test to be executed once the logging framework is initialized. */
static void Register(SelfTestFunction a_FnToExecute, const AString & a_TestName);
/** Executes all the registered self-tests. */
static void ExecuteAll(void);
protected:
typedef std::vector<std::pair<SelfTestFunction, AString>> SelfTestFunctions;
/** Functions (registered self-tests) to call once the logging framework is initialized. */
SelfTestFunctions m_SelfTests;
/** If true, tests may be registered. Set to false once the tests are executed, to detect tests that are registered too late. */
bool m_AllowRegistering;
cSelfTests(void);
};
#endif // SELF_TEST

View File

@ -9,42 +9,6 @@
#include "FastNBT.h"
#include "SchematicFileSerializer.h"
#include "../StringCompression.h"
#include "../SelfTests.h"
#ifdef SELF_TEST
static class cSchematicStringSelfTest
{
public:
cSchematicStringSelfTest(void)
{
cSelfTests::Get().Register(cSelfTests::SelfTestFunction(&Test), "Schematic-to-string serialization");
}
static void Test(void)
{
cBlockArea ba;
ba.Create(21, 256, 21);
ba.RelLine(0, 0, 0, 9, 8, 7, cBlockArea::baTypes | cBlockArea::baMetas, E_BLOCK_WOODEN_STAIRS, 1);
AString Schematic;
if (!cSchematicFileSerializer::SaveToSchematicString(ba, Schematic))
{
assert_test(!"Schematic failed to save!");
}
cBlockArea ba2;
if (!cSchematicFileSerializer::LoadFromSchematicString(ba2, Schematic))
{
assert_test(!"Schematic failed to load!");
}
}
} g_SelfTest;
#endif

View File

@ -0,0 +1,80 @@
// ByteBufferTest.cpp
// Implements the main app entrypoint for the cByteBuffer class test
#include "Globals.h"
#include "BoundingBox.h"
/** Runs the tests, returns the number of failed tests. */
static int Test(void)
{
int NumFailed = 0;
Vector3d Min(1, 1, 1);
Vector3d Max(2, 2, 2);
Vector3d LineDefs[] =
{
Vector3d(1.5, 4, 1.5), Vector3d(1.5, 3, 1.5), // Should intersect at 2, face 1 (YP)
Vector3d(1.5, 0, 1.5), Vector3d(1.5, 4, 1.5), // Should intersect at 0.25, face 0 (YM)
Vector3d(0, 0, 0), Vector3d(2, 2, 2), // Should intersect at 0.5, face 0, 3 or 5 (anyM)
Vector3d(0.999, 0, 1.5), Vector3d(0.999, 4, 1.5), // Should not intersect
Vector3d(1.999, 0, 1.5), Vector3d(1.999, 4, 1.5), // Should intersect at 0.25, face 0 (YM)
Vector3d(2.001, 0, 1.5), Vector3d(2.001, 4, 1.5), // Should not intersect
} ;
bool Results[] = {true, true, true, false, true, false};
double LineCoeffs[] = {2, 0.25, 0.5, 0, 0.25, 0};
for (size_t i = 0; i < ARRAYCOUNT(LineDefs) / 2; i++)
{
double LineCoeff;
eBlockFace Face;
Vector3d Line1 = LineDefs[2 * i];
Vector3d Line2 = LineDefs[2 * i + 1];
bool res = cBoundingBox::CalcLineIntersection(Min, Max, Line1, Line2, LineCoeff, Face);
if (res != Results[i])
{
LOGERROR("LineIntersection({%.02f, %.02f, %.02f}, {%.02f, %.02f, %.02f}) -> %d, %.05f, %d",
Line1.x, Line1.y, Line1.z,
Line2.x, Line2.y, Line2.z,
res ? 1 : 0, LineCoeff, Face
);
NumFailed += 1;
}
if (res)
{
if (LineCoeff != LineCoeffs[i])
{
LOGERROR("LineIntersection({%.02f, %.02f, %.02f}, {%.02f, %.02f, %.02f}) -> %d, %.05f, %d",
Line1.x, Line1.y, Line1.z,
Line2.x, Line2.y, Line2.z,
res ? 1 : 0, LineCoeff, Face
);
NumFailed += 1;
}
}
} // for i - LineDefs[]
return 0;
}
int main(int argc, char * argv[])
{
LOGD("Test started");
LOGD("Running test");
auto NumFailed = Test();
LOG("BoundingBox test finished, number of failed tests: %d", NumFailed);
return NumFailed;
}

View File

@ -0,0 +1,47 @@
cmake_minimum_required (VERSION 2.6)
enable_testing()
add_definitions(-DTEST_GLOBALS=1)
include_directories(${CMAKE_SOURCE_DIR}/src/)
add_definitions(-DTEST_GLOBALS=1)
set (SHARED_SRCS
${CMAKE_SOURCE_DIR}/src/BoundingBox.cpp
${CMAKE_SOURCE_DIR}/src/OSSupport/StackTrace.cpp
)
set (SHARED_HDRS
${CMAKE_SOURCE_DIR}/src/BoundingBox.h
${CMAKE_SOURCE_DIR}/src/OSSupport/StackTrace.h
)
set (SRCS
BoundingBoxTest.cpp
)
if (MSVC)
# Add the MSVC-specific LeakFinder / StackTracer sources:
list (APPEND SHARED_SRCS ${CMAKE_SOURCE_DIR}/src/LeakFinder.cpp ${CMAKE_SOURCE_DIR}/src/StackWalker.cpp)
list (APPEND SHARED_HDRS ${CMAKE_SOURCE_DIR}/src/LeakFinder.h ${CMAKE_SOURCE_DIR}/src/StackWalker.h)
endif()
if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang")
add_flags_cxx("-Wno-error=float-equal")
endif()
source_group("Shared" FILES ${SHARED_SRCS} ${SHARED_HDRS})
source_group("Sources" FILES ${SRCS})
add_executable(BoundingBox-exe ${SRCS} ${SHARED_SRCS} ${SHARED_HDRS})
add_test(NAME BoundingBox-test COMMAND BoundingBox-exe)
# Put the projects into solution folders (MSVC):
set_target_properties(
BoundingBox-exe
PROPERTIES FOLDER Tests
)

View File

@ -0,0 +1,88 @@
// ByteBufferTest.cpp
// Implements the main app entrypoint for the cByteBuffer class test
#include "Globals.h"
#include "ByteBuffer.h"
static void TestRead(void)
{
cByteBuffer buf(50);
buf.Write("\x05\xac\x02\x00", 4);
UInt32 v1;
assert_test(buf.ReadVarInt(v1) && (v1 == 5));
UInt32 v2;
assert_test(buf.ReadVarInt(v2) && (v2 == 300));
UInt32 v3;
assert_test(buf.ReadVarInt(v3) && (v3 == 0));
}
static void TestWrite(void)
{
cByteBuffer buf(50);
buf.WriteVarInt32(5);
buf.WriteVarInt32(300);
buf.WriteVarInt32(0);
AString All;
buf.ReadAll(All);
assert_test(All.size() == 4);
assert_test(memcmp(All.data(), "\x05\xac\x02\x00", All.size()) == 0);
}
static void TestWrap(void)
{
cByteBuffer buf(3);
for (int i = 0; i < 1000; i++)
{
size_t FreeSpace = buf.GetFreeSpace();
assert_test(buf.GetReadableSpace() == 0);
assert_test(FreeSpace > 0);
assert_test(buf.Write("a", 1));
assert_test(buf.CanReadBytes(1));
assert_test(buf.GetReadableSpace() == 1);
UInt8 v = 0;
assert_test(buf.ReadBEUInt8(v));
assert_test(v == 'a');
assert_test(buf.GetReadableSpace() == 0);
buf.CommitRead();
assert_test(buf.GetFreeSpace() == FreeSpace); // We're back to normal
}
}
int main(int argc, char * argv[])
{
LOGD("Test started");
LOGD("Testing reads");
TestRead();
LOGD("Testing writes");
TestWrite();
LOGD("Testing wraps");
TestWrap();
LOG("ByteBuffer test finished.");
}

View File

@ -0,0 +1,46 @@
cmake_minimum_required (VERSION 2.6)
enable_testing()
add_definitions(-DTEST_GLOBALS=1)
include_directories(${CMAKE_SOURCE_DIR}/src/)
add_definitions(-DTEST_GLOBALS=1)
set (SHARED_SRCS
${CMAKE_SOURCE_DIR}/src/ByteBuffer.cpp
${CMAKE_SOURCE_DIR}/src/OSSupport/StackTrace.cpp
)
set (SHARED_HDRS
${CMAKE_SOURCE_DIR}/src/ByteBuffer.h
${CMAKE_SOURCE_DIR}/src/OSSupport/StackTrace.h
)
set (SRCS
ByteBufferTest.cpp
)
if (MSVC)
# Add the MSVC-specific LeakFinder / StackTracer sources:
list (APPEND SHARED_SRCS ${CMAKE_SOURCE_DIR}/src/LeakFinder.cpp ${CMAKE_SOURCE_DIR}/src/StackWalker.cpp)
list (APPEND SHARED_HDRS ${CMAKE_SOURCE_DIR}/src/LeakFinder.h ${CMAKE_SOURCE_DIR}/src/StackWalker.h)
endif()
source_group("Shared" FILES ${SHARED_SRCS} ${SHARED_HDRS})
source_group("Sources" FILES ${SRCS})
add_executable(ByteBuffer-exe ${SRCS} ${SHARED_SRCS} ${SHARED_HDRS})
if (WIN32)
target_link_libraries(ByteBuffer-exe ws2_32)
endif()
add_test(NAME ByteBuffer-test COMMAND ByteBuffer-exe)
# Put the projects into solution folders (MSVC):
set_target_properties(
ByteBuffer-exe
PROPERTIES FOLDER Tests
)

View File

@ -6,9 +6,13 @@ if (CMAKE_BUILD_TYPE STREQUAL "COVERAGE")
setup_target_for_coverage("${PROJECT_NAME}_coverage" "ctest" coverage)
endif()
include_directories(${CMAKE_CURRENT_SOURCE_DIR})
# include_directories(${CMAKE_CURRENT_SOURCE_DIR})
add_subdirectory(BoundingBox)
add_subdirectory(ByteBuffer)
add_subdirectory(ChunkData)
add_subdirectory(CompositeChat)
add_subdirectory(HTTP)
add_subdirectory(Network)
add_subdirectory(LoadablePieces)
add_subdirectory(Network)
add_subdirectory(SchematicFileSerializer)

View File

@ -6,6 +6,8 @@
int main(int argc, char** argv)
{
LOGD("Test started");
class cMockAllocationPool
: public cAllocationPool<cChunkData::sChunkSection>
{

View File

@ -33,3 +33,20 @@ add_test(NAME arraystocoords-test COMMAND arraystocoords-exe)
add_executable(copyblocks-exe CopyBlocks.cpp)
target_link_libraries(copyblocks-exe ChunkBuffer)
add_test(NAME copyblocks-test COMMAND copyblocks-exe)
# Put all test projects into a separate folder:
set_target_properties(
arraystocoords-exe
coordinates-exe
copies-exe
copyblocks-exe
creatable-exe
PROPERTIES FOLDER Tests/ChunkData
)
set_target_properties(
ChunkBuffer
PROPERTIES FOLDER Lib
)

View File

@ -6,6 +6,8 @@
int main(int argc, char** argv)
{
LOGD("Test started");
class cMockAllocationPool
: public cAllocationPool<cChunkData::sChunkSection>
{

View File

@ -6,6 +6,8 @@
int main(int argc, char** argv)
{
LOGD("Test started");
class cMockAllocationPool
: public cAllocationPool<cChunkData::sChunkSection>
{

View File

@ -16,6 +16,8 @@
int main(int argc, char ** argv)
{
LOGD("Test started");
// Set up a cChunkData with known contents - all blocks 0x01, all metas 0x02:
class cMockAllocationPool
: public cAllocationPool<cChunkData::sChunkSection>

View File

@ -4,6 +4,8 @@
int main(int argc, char** argv)
{
LOGD("Test started");
class cMockAllocationPool
: public cAllocationPool<cChunkData::sChunkSection>
{

View File

@ -0,0 +1,47 @@
cmake_minimum_required (VERSION 2.6)
enable_testing()
add_definitions(-DTEST_GLOBALS=1)
include_directories(${CMAKE_CURRENT_SOURCE_DIR})
include_directories(${CMAKE_SOURCE_DIR}/src/)
include_directories(${CMAKE_SOURCE_DIR}/lib/jsoncpp/include)
add_definitions(-DTEST_GLOBALS=1)
set (SHARED_SRCS
${CMAKE_SOURCE_DIR}/src/CompositeChat.cpp
${CMAKE_SOURCE_DIR}/src/OSSupport/StackTrace.cpp
)
set (SHARED_HDRS
${CMAKE_SOURCE_DIR}/src/CompositeChat.h
${CMAKE_SOURCE_DIR}/src/OSSupport/StackTrace.h
)
set (SRCS
CompositeChatTest.cpp
ClientHandle.cpp
)
if (MSVC)
# Add the MSVC-specific LeakFinder / StackTracer sources:
list (APPEND SHARED_SRCS ${CMAKE_SOURCE_DIR}/src/LeakFinder.cpp ${CMAKE_SOURCE_DIR}/src/StackWalker.cpp)
list (APPEND SHARED_HDRS ${CMAKE_SOURCE_DIR}/src/LeakFinder.h ${CMAKE_SOURCE_DIR}/src/StackWalker.h)
endif()
source_group("Shared" FILES ${SHARED_SRCS} ${SHARED_HDRS})
source_group("Sources" FILES ${SRCS})
add_executable(CompositeChat-exe ${SRCS} ${SHARED_SRCS} ${SHARED_HDRS})
target_link_libraries(CompositeChat-exe jsoncpp_lib_static)
add_test(NAME CompositeChat-test COMMAND CompositeChat-exe)
# Put the projects into solution folders (MSVC):
set_target_properties(
CompositeChat-exe
PROPERTIES FOLDER Tests
)

View File

@ -0,0 +1,20 @@
// ClientHandle.cpp
// Mocks the cClientHandle class used by the tests
#include "Globals.h"
#include "ClientHandle.h"
AString cClientHandle::FormatMessageType(bool a_ShouldShowPrefixes, eMessageType a_MsgType, const AString & a_AdditionalData)
{
return "<FormatMessageType mocked>";
}

View File

@ -0,0 +1,124 @@
// CompositeChatTest.cpp
// Implements the main app entrypoint for the cCompositeChat class test
#include "Globals.h"
#include "CompositeChat.h"
static void TestParser1(void)
{
cCompositeChat Msg;
Msg.ParseText("Testing @2color codes and http://links parser");
const cCompositeChat::cParts & Parts = Msg.GetParts();
assert_test(Parts.size() == 4);
assert_test(Parts[0]->m_PartType == cCompositeChat::ptText);
assert_test(Parts[1]->m_PartType == cCompositeChat::ptText);
assert_test(Parts[2]->m_PartType == cCompositeChat::ptUrl);
assert_test(Parts[3]->m_PartType == cCompositeChat::ptText);
assert_test(Parts[0]->m_Style == "");
assert_test(Parts[1]->m_Style == "@2");
assert_test(Parts[2]->m_Style == "@2");
assert_test(Parts[3]->m_Style == "@2");
}
static void TestParser2(void)
{
cCompositeChat Msg;
Msg.ParseText("@3Advanced stuff: @5overriding color codes and http://links.with/@4color-in-them handling");
const cCompositeChat::cParts & Parts = Msg.GetParts();
assert_test(Parts.size() == 4);
assert_test(Parts[0]->m_PartType == cCompositeChat::ptText);
assert_test(Parts[1]->m_PartType == cCompositeChat::ptText);
assert_test(Parts[2]->m_PartType == cCompositeChat::ptUrl);
assert_test(Parts[3]->m_PartType == cCompositeChat::ptText);
assert_test(Parts[0]->m_Style == "@3");
assert_test(Parts[1]->m_Style == "@5");
assert_test(Parts[2]->m_Style == "@5");
assert_test(Parts[3]->m_Style == "@5");
}
static void TestParser3(void)
{
cCompositeChat Msg;
Msg.ParseText("http://links.starting the text");
const cCompositeChat::cParts & Parts = Msg.GetParts();
assert_test(Parts.size() == 2);
assert_test(Parts[0]->m_PartType == cCompositeChat::ptUrl);
assert_test(Parts[1]->m_PartType == cCompositeChat::ptText);
assert_test(Parts[0]->m_Style == "");
assert_test(Parts[1]->m_Style == "");
}
static void TestParser4(void)
{
cCompositeChat Msg;
Msg.ParseText("links finishing the text: http://some.server");
const cCompositeChat::cParts & Parts = Msg.GetParts();
assert_test(Parts.size() == 2);
assert_test(Parts[0]->m_PartType == cCompositeChat::ptText);
assert_test(Parts[1]->m_PartType == cCompositeChat::ptUrl);
assert_test(Parts[0]->m_Style == "");
assert_test(Parts[1]->m_Style == "");
}
static void TestParser5(void)
{
cCompositeChat Msg;
Msg.ParseText("http://only.links");
const cCompositeChat::cParts & Parts = Msg.GetParts();
assert_test(Parts.size() == 1);
assert_test(Parts[0]->m_PartType == cCompositeChat::ptUrl);
assert_test(Parts[0]->m_Style == "");
}
int main(int argc, char * argv[])
{
LOGD("Test started.");
LOGD("Running tests: 1");
TestParser1();
LOGD("Running tests: 2");
TestParser2();
LOGD("Running tests: 3");
TestParser3();
LOGD("Running tests: 4");
TestParser4();
LOGD("Running tests: 5");
TestParser5();
LOG("CompositeChat test finished.");
}

View File

@ -44,17 +44,30 @@ add_executable(HTTPMessageParser_file-exe HTTPMessageParser_file.cpp)
target_link_libraries(HTTPMessageParser_file-exe HTTP)
# Test parsing the response file in 2-byte chunks (should go from response line parsing through headers parsing to body parsing, each within a different step):
add_test(NAME HTTPMessageParser_file-test1-2 COMMAND HTTPMessageParser_file-exe HTTPResponse1.data 2)
add_test(NAME HTTPMessageParser_file-test1-2 COMMAND HTTPMessageParser_file-exe ${CMAKE_CURRENT_SOURCE_DIR}/HTTPResponse1.data 2)
# Test parsing the response file in 128-byte chunks (should parse response line and part of headers in one step, the rest in another step):
add_test(NAME HTTPMessageParser_file-test1-128 COMMAND HTTPMessageParser_file-exe HTTPResponse1.data 128)
add_test(NAME HTTPMessageParser_file-test1-128 COMMAND HTTPMessageParser_file-exe ${CMAKE_CURRENT_SOURCE_DIR}/HTTPResponse1.data 128)
# Test parsing a chunked-encoding response:
add_test(NAME HTTPMessageParser_file-test2 COMMAND HTTPMessageParser_file-exe HTTPResponse2.data)
add_test(NAME HTTPMessageParser_file-test2 COMMAND HTTPMessageParser_file-exe ${CMAKE_CURRENT_SOURCE_DIR}/HTTPResponse2.data)
# Test parsing the request file in 2-byte chunks (should go from request line parsing through headers parsing to body parsing, each within a different step):
add_test(NAME HTTPMessageParser_file-test3-2 COMMAND HTTPMessageParser_file-exe HTTPRequest1.data 2)
add_test(NAME HTTPMessageParser_file-test3-2 COMMAND HTTPMessageParser_file-exe ${CMAKE_CURRENT_SOURCE_DIR}/HTTPRequest1.data 2)
# Test parsing the request file in 512-byte chunks (should process everything in a single call):
add_test(NAME HTTPMessageParser_file-test4-512 COMMAND HTTPMessageParser_file-exe HTTPRequest1.data 512)
add_test(NAME HTTPMessageParser_file-test4-512 COMMAND HTTPMessageParser_file-exe ${CMAKE_CURRENT_SOURCE_DIR}/HTTPRequest1.data 512)
# Put all the tests into a solution folder (MSVC):
set_target_properties(
HTTPMessageParser_file-exe
PROPERTIES FOLDER Tests
)
set_target_properties(
HTTP
PROPERTIES FOLDER Lib
)

View File

@ -71,7 +71,7 @@ public:
int main(int argc, char * argv[])
{
printf("HTTPMessageParser_file beginning\n");
LOGD("Test started");
// Open the input file:
if (argc <= 1)

View File

@ -98,3 +98,8 @@ add_test(NAME LoadablePieces-test WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
# Put the projects into solution folders (MSVC):
set_target_properties(
LoadablePieces
PROPERTIES FOLDER Tests
)

View File

@ -41,6 +41,8 @@ static int DoTest(void)
int main(int argc, char * argv[])
{
LOGD("Test started");
// Print the current directory for reference:
char folder[FILENAME_MAX];
GetCurrentFolder(folder, sizeof(folder));

View File

@ -6,7 +6,6 @@
#include "Globals.h"
#include "BlockInfo.h"
#include "SelfTests.h"
#include "Bindings.h"
#include "Bindings/DeprecatedBindings.h"
#include "Bindings/LuaJson.h"
@ -272,30 +271,3 @@ cBlockEntity * cBlockEntity::CreateByBlockType(BLOCKTYPE a_BlockType, NIBBLETYPE
cSelfTests::cSelfTests(void):
m_AllowRegistering(true)
{
}
cSelfTests & cSelfTests::Get(void)
{
static cSelfTests singleton;
return singleton;
}
void cSelfTests::Register(cSelfTests::SelfTestFunction a_TestFn, const AString & a_TestName)
{
}

View File

@ -13,6 +13,7 @@ set (Network_SRCS
${CMAKE_SOURCE_DIR}/src/OSSupport/Event.cpp
${CMAKE_SOURCE_DIR}/src/OSSupport/HostnameLookup.cpp
${CMAKE_SOURCE_DIR}/src/OSSupport/IPLookup.cpp
${CMAKE_SOURCE_DIR}/src/OSSupport/NetworkInterfaceEnum.cpp
${CMAKE_SOURCE_DIR}/src/OSSupport/NetworkSingleton.cpp
${CMAKE_SOURCE_DIR}/src/OSSupport/ServerHandleImpl.cpp
${CMAKE_SOURCE_DIR}/src/OSSupport/TCPLinkImpl.cpp
@ -62,3 +63,28 @@ target_link_libraries(EchoServer Network)
# NameLookup: Lookup hostname-to-IP and IP-to-hostname:
add_executable(NameLookup NameLookup.cpp)
target_link_libraries(NameLookup Network)
# EnumInterfaces: List all network interfaces:
add_executable(EnumInterfaces-exe EnumInterfaces.cpp)
target_link_libraries(EnumInterfaces-exe Network)
add_test(NAME EnumInterfaces-test COMMAND EnumInterfaces-exe)
# Put all the tests into a solution folder (MSVC):
set_target_properties(
EchoServer
Google-exe
NameLookup
EnumInterfaces-exe
PROPERTIES FOLDER Tests/Network
)
set_target_properties(
Network
PROPERTIES FOLDER Lib
)

View File

@ -75,7 +75,7 @@ class cEchoLinkCallbacks:
class cEchoServerCallbacks:
public cNetwork::cListenCallbacks
{
virtual cTCPLink::cCallbacksPtr OnIncomingConnection(const AString & a_RemoteIPAddress, UInt16 a_RemotePort)
virtual cTCPLink::cCallbacksPtr OnIncomingConnection(const AString & a_RemoteIPAddress, UInt16 a_RemotePort) override
{
LOGD("New incoming connection(%s:%d).", a_RemoteIPAddress.c_str(), a_RemotePort);
return std::make_shared<cEchoLinkCallbacks>();

View File

@ -0,0 +1,39 @@
// EnumInterfaces.cpp
// Implements the main app entrypoint for the EnumInterfaces network test
// Lists all network interfaces to the console
#include "Globals.h"
#include "OSSupport/Network.h"
#include "OSSupport/NetworkSingleton.h"
int main(int argc, char * argv[])
{
// Initialize the cNetwork subsystem:
LOGD("Initializing cNetwork...");
cNetworkSingleton::Get().Initialise();
// Enumerate all the addresses:
printf("Enumerating all IP addresses...\n");
auto IPs = cNetwork::EnumLocalIPAddresses();
for (auto & ip: IPs)
{
LOGD(" %s", ip.c_str());
}
LOGD("All addresses enumerated.");
// Terminate the cNetwork subsystem:
cNetworkSingleton::Get().Terminate();
LOGD("Test finished.");
return 0;
}

View File

@ -118,7 +118,10 @@ static void DoTest(void)
int main()
{
LOGD("Initializing cNetwork...\n");
cNetworkSingleton::Get().Initialise();
LOGD("Testing...");
DoTest();
cNetworkSingleton::Get().Terminate();

View File

@ -79,7 +79,12 @@ static void DoTest(void)
int main()
{
LOGD("Initializing cNetwork...");
cNetworkSingleton::Get().Initialise();
LOGD("Running test...");
DoTest();
cNetworkSingleton::Get().Terminate();
LOGD("Network test finished");
return 0;

View File

@ -0,0 +1,93 @@
cmake_minimum_required (VERSION 2.6)
enable_testing()
include_directories(${CMAKE_SOURCE_DIR}/src/)
include_directories(${CMAKE_SOURCE_DIR}/lib/)
include_directories(${CMAKE_CURRENT_SOURCE_DIR})
add_definitions(-DTEST_GLOBALS=1)
set (SHARED_SRCS
${CMAKE_SOURCE_DIR}/src/BiomeDef.cpp
${CMAKE_SOURCE_DIR}/src/BlockArea.cpp
${CMAKE_SOURCE_DIR}/src/Cuboid.cpp
${CMAKE_SOURCE_DIR}/src/ChunkData.cpp
${CMAKE_SOURCE_DIR}/src/StringCompression.cpp
${CMAKE_SOURCE_DIR}/src/StringUtils.cpp
${CMAKE_SOURCE_DIR}/src/Noise/Noise.cpp
${CMAKE_SOURCE_DIR}/src/OSSupport/CriticalSection.cpp
${CMAKE_SOURCE_DIR}/src/OSSupport/Event.cpp
${CMAKE_SOURCE_DIR}/src/OSSupport/File.cpp
${CMAKE_SOURCE_DIR}/src/OSSupport/GZipFile.cpp
${CMAKE_SOURCE_DIR}/src/OSSupport/StackTrace.cpp
${CMAKE_SOURCE_DIR}/src/WorldStorage/FastNBT.cpp
${CMAKE_SOURCE_DIR}/src/WorldStorage/SchematicFileSerializer.cpp
)
set (SHARED_HDRS
${CMAKE_SOURCE_DIR}/src/BiomeDef.h
${CMAKE_SOURCE_DIR}/src/BlockArea.h
${CMAKE_SOURCE_DIR}/src/Cuboid.h
${CMAKE_SOURCE_DIR}/src/ChunkData.h
${CMAKE_SOURCE_DIR}/src/Globals.h
${CMAKE_SOURCE_DIR}/src/StringCompression.h
${CMAKE_SOURCE_DIR}/src/StringUtils.h
${CMAKE_SOURCE_DIR}/src/Bindings/LuaState.h
${CMAKE_SOURCE_DIR}/src/Generating/ChunkDesc.h
${CMAKE_SOURCE_DIR}/src/Generating/PieceGenerator.h
${CMAKE_SOURCE_DIR}/src/Generating/Prefab.h
${CMAKE_SOURCE_DIR}/src/Generating/PrefabPiecePool.h
${CMAKE_SOURCE_DIR}/src/Generating/VerticalLimit.h
${CMAKE_SOURCE_DIR}/src/Generating/VerticalStrategy.h
${CMAKE_SOURCE_DIR}/src/Noise/Noise.h
${CMAKE_SOURCE_DIR}/src/OSSupport/CriticalSection.h
${CMAKE_SOURCE_DIR}/src/OSSupport/Event.h
${CMAKE_SOURCE_DIR}/src/OSSupport/File.h
${CMAKE_SOURCE_DIR}/src/OSSupport/GZipFile.h
${CMAKE_SOURCE_DIR}/src/OSSupport/StackTrace.h
${CMAKE_SOURCE_DIR}/src/WorldStorage/FastNBT.h
${CMAKE_SOURCE_DIR}/src/WorldStorage/SchematicFileSerializer.h
)
set (SRCS
SchematicFileSerializerTest.cpp
Stubs.cpp
)
if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang")
add_flags_cxx("-Wno-error=conversion -Wno-error=old-style-cast")
add_flags_cxx("-Wno-error=global-constructors")
add_flags_cxx("-Wno-error=switch-enum")
endif()
if (MSVC)
# Add the MSVC-specific LeakFinder sources:
list (APPEND SHARED_SRCS ${CMAKE_SOURCE_DIR}/src/LeakFinder.cpp ${CMAKE_SOURCE_DIR}/src/StackWalker.cpp)
list (APPEND SHARED_HDRS ${CMAKE_SOURCE_DIR}/src/LeakFinder.h ${CMAKE_SOURCE_DIR}/src/StackWalker.h)
endif()
source_group("Shared" FILES ${SHARED_SRCS} ${SHARED_HDRS})
source_group("Sources" FILES ${SRCS})
add_executable(SchematicFileSerializer-exe ${SRCS} ${SHARED_SRCS} ${SHARED_HDRS})
target_link_libraries(SchematicFileSerializer-exe zlib)
add_test(NAME SchematicFileSerializer-test WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} COMMAND SchematicFileSerializer-exe)
# Put the projects into solution folders (MSVC):
set_target_properties(
SchematicFileSerializer-exe
PROPERTIES FOLDER Tests
)

View File

@ -0,0 +1,43 @@
// SchematicFileSerializerTest.cpp
// Implements the SchematicFileSerializer test main entrypoint
#include "Globals.h"
#include "WorldStorage/SchematicFileSerializer.h"
static void DoTest(void)
{
cBlockArea ba;
ba.Create(21, 256, 21);
ba.RelLine(0, 0, 0, 9, 8, 7, cBlockArea::baTypes | cBlockArea::baMetas, E_BLOCK_WOODEN_STAIRS, 1);
AString Schematic;
if (!cSchematicFileSerializer::SaveToSchematicString(ba, Schematic))
{
assert_test(!"Schematic failed to save!");
}
cBlockArea ba2;
if (!cSchematicFileSerializer::LoadFromSchematicString(ba2, Schematic))
{
assert_test(!"Schematic failed to load!");
}
}
int main(int argc, char * argv[])
{
DoTest();
LOG("SchematicFileSerializer test done.");
return 0;
}

View File

@ -0,0 +1,193 @@
// Stubs.cpp
// Implements stubs of various Cuberite methods that are needed for linking but not for runtime
// This is required so that we don't bring in the entire Cuberite via dependencies
#include "Globals.h"
#include "BlockInfo.h"
#include "Blocks/BlockHandler.h"
cBlockInfo::~cBlockInfo()
{
}
void cBlockInfo::Initialize(cBlockInfo::cBlockInfoArray & a_BlockInfos)
{
// The piece-loading code uses the handlers for rotations, so we need valid handlers
// Insert dummy handlers:
for (size_t i = 0; i < ARRAYCOUNT(a_BlockInfos); i++)
{
a_BlockInfos[i].m_Handler = new cBlockHandler(static_cast<BLOCKTYPE>(i));
}
}
cBlockHandler::cBlockHandler(BLOCKTYPE a_BlockType)
{
}
bool cBlockHandler::GetPlacementBlockTypeMeta(
cChunkInterface & a_ChunkInterface, cPlayer * a_Player,
int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_BlockFace,
int a_CursorX, int a_CursorY, int a_CursorZ,
BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta
)
{
return true;
}
void cBlockHandler::OnUpdate(cChunkInterface & cChunkInterface, cWorldInterface & a_WorldInterface, cBlockPluginInterface & a_PluginInterface, cChunk & a_Chunk, int a_BlockX, int a_BlockY, int a_BlockZ)
{
}
void cBlockHandler::OnPlacedByPlayer(cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface, cPlayer * a_Player, const sSetBlock & a_BlockChange)
{
}
void cBlockHandler::OnDestroyedByPlayer(cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface, cPlayer * a_Player, int a_BlockX, int a_BlockY, int a_BlockZ)
{
}
void cBlockHandler::OnPlaced(cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface, int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta)
{
}
void cBlockHandler::OnDestroyed(cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface, int a_BlockX, int a_BlockY, int a_BlockZ)
{
}
void cBlockHandler::NeighborChanged(cChunkInterface & a_ChunkInterface, int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_WhichNeighbor)
{
}
void cBlockHandler::ConvertToPickups(cItems & a_Pickups, NIBBLETYPE a_BlockMeta)
{
}
void cBlockHandler::DropBlock(cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface, cBlockPluginInterface & a_BlockPluginInterface, cEntity * a_Digger, int a_BlockX, int a_BlockY, int a_BlockZ, bool a_CanDrop)
{
}
bool cBlockHandler::CanBeAt(cChunkInterface & a_ChunkInterface, int a_BlockX, int a_BlockY, int a_BlockZ, const cChunk & a_Chunk)
{
return true;
}
bool cBlockHandler::IsUseable()
{
return false;
}
bool cBlockHandler::IsClickedThrough(void)
{
return false;
}
bool cBlockHandler::DoesIgnoreBuildCollision(void)
{
return (m_BlockType == E_BLOCK_AIR);
}
bool cBlockHandler::DoesDropOnUnsuitable(void)
{
return true;
}
void cBlockHandler::Check(cChunkInterface & a_ChunkInterface, cBlockPluginInterface & a_PluginInterface, int a_RelX, int a_RelY, int a_RelZ, cChunk & a_Chunk)
{
}
ColourID cBlockHandler::GetMapBaseColourID(NIBBLETYPE a_Meta)
{
return 0;
}
bool cBlockHandler::IsInsideBlock(const Vector3d & a_Position, const BLOCKTYPE a_BlockType, const NIBBLETYPE a_BlockMeta)
{
return true;
}