forked from Mirrors/openclonk
Aul tests: Assert that Translate() warns when a translation is missing
I'm not a huge fan of testing for warnings by hijacking the logging routines, but right now there's no way to exfiltrate warnings from Aul any other way, so it'll have to do. Overriding the logging functions from C4SimpleLog.cpp has the nice additional advantage that expected runtime errors no longer get written to stdout - this is okay because we're already checking that an exception is thrown.objectmenu
parent
53fe0fa1cc
commit
b7cffa5e82
|
@ -88,9 +88,15 @@ function(create_test testName)
|
|||
set(oneValueArgs "")
|
||||
set(multiValueArgs SOURCES LIBRARIES)
|
||||
CMAKE_PARSE_ARGUMENTS(CT "" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
|
||||
add_executable("${testName}" EXCLUDE_FROM_ALL ${CT_SOURCES} main.cpp)
|
||||
add_executable("${testName}" EXCLUDE_FROM_ALL
|
||||
${CT_SOURCES}
|
||||
TestLog.cpp
|
||||
TestLog.h
|
||||
main.cpp
|
||||
)
|
||||
target_include_directories("${testName}" PRIVATE "${CMAKE_CURRENT_LIST_DIR}")
|
||||
set_property(TARGET "${testName}" PROPERTY FOLDER "Testing")
|
||||
target_link_libraries("${testName}" gtest ${CT_LIBRARIES})
|
||||
target_link_libraries("${testName}" gtest gmock ${CT_LIBRARIES})
|
||||
add_test(NAME "${testName}" COMMAND "${testName}")
|
||||
endfunction()
|
||||
|
||||
|
|
|
@ -0,0 +1,69 @@
|
|||
/*
|
||||
* OpenClonk, http://www.openclonk.org
|
||||
*
|
||||
* Copyright (c) 2016, The OpenClonk Team and contributors
|
||||
*
|
||||
* Distributed under the terms of the ISC license; see accompanying file
|
||||
* "COPYING" for details.
|
||||
*
|
||||
* "Clonk" is a registered trademark of Matthes Bender, used with permission.
|
||||
* See accompanying file "TRADEMARK" for details.
|
||||
*
|
||||
* To redistribute this file separately, substitute the full license texts
|
||||
* for the above references.
|
||||
*/
|
||||
|
||||
// Proxies the logging functions into a class so we can test that something
|
||||
// gets logged
|
||||
|
||||
#include "TestLog.h"
|
||||
|
||||
// Override ALL of the C4SimpleLog.cpp functions here because otherwise MSVC
|
||||
// pulls the .obj in and will end up with multiple definitions of a symbol.
|
||||
#define FORWARD_UNFORMATTED(func) bool func(const char *msg) { return TestLog::handler ? TestLog::handler->func(msg) : true; }
|
||||
FORWARD_UNFORMATTED(Log)
|
||||
FORWARD_UNFORMATTED(DebugLog)
|
||||
FORWARD_UNFORMATTED(LogSilent)
|
||||
FORWARD_UNFORMATTED(LogFatal)
|
||||
#undef FORWARD_UNFORMATTED
|
||||
|
||||
#define FORWARD_FORMATTED(func) bool func(const char *msg, ...) \
|
||||
{ \
|
||||
va_list args; va_start(args, msg); \
|
||||
bool result = TestLog::handler ? TestLog::handler->func(msg, args) : true; \
|
||||
va_end(args); \
|
||||
return result; \
|
||||
}
|
||||
FORWARD_FORMATTED(DebugLogF)
|
||||
FORWARD_FORMATTED(LogF)
|
||||
FORWARD_FORMATTED(LogSilentF)
|
||||
#undef FORWARD_FORMATTED
|
||||
|
||||
TestLog *TestLog::handler = 0;
|
||||
|
||||
void TestLog::setHandler(TestLog *new_handler)
|
||||
{
|
||||
handler = new_handler;
|
||||
}
|
||||
|
||||
TestLog::TestLog()
|
||||
{
|
||||
setHandler(this);
|
||||
}
|
||||
|
||||
TestLog::~TestLog()
|
||||
{
|
||||
// Make sure there's no deleted logging handler set
|
||||
if (handler == this)
|
||||
handler = 0;
|
||||
}
|
||||
|
||||
// Default implementation does nothing
|
||||
bool TestLog::Log(const char * /* msg */) { return true; }
|
||||
bool TestLog::DebugLog(const char * /* msg */) { return true; }
|
||||
bool TestLog::LogFatal(const char * /* msg */) { return true; }
|
||||
bool TestLog::LogSilent(const char * /* msg */) { return true; }
|
||||
|
||||
bool TestLog::LogF(const char * /* msg */, va_list /* args */) { return true; }
|
||||
bool TestLog::DebugLogF(const char * /* msg */, va_list /* args */) { return true; }
|
||||
bool TestLog::LogSilentF(const char * /* msg */, va_list /* args */) { return true; }
|
|
@ -0,0 +1,59 @@
|
|||
/*
|
||||
* OpenClonk, http://www.openclonk.org
|
||||
*
|
||||
* Copyright (c) 2016, The OpenClonk Team and contributors
|
||||
*
|
||||
* Distributed under the terms of the ISC license; see accompanying file
|
||||
* "COPYING" for details.
|
||||
*
|
||||
* "Clonk" is a registered trademark of Matthes Bender, used with permission.
|
||||
* See accompanying file "TRADEMARK" for details.
|
||||
*
|
||||
* To redistribute this file separately, substitute the full license texts
|
||||
* for the above references.
|
||||
*/
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <gmock/gmock.h>
|
||||
|
||||
class TestLog
|
||||
{
|
||||
public:
|
||||
virtual ~TestLog();
|
||||
static void setHandler(TestLog *new_handler);
|
||||
|
||||
protected:
|
||||
virtual bool Log(const char *msg) = 0;
|
||||
virtual bool DebugLog(const char *msg) = 0;
|
||||
virtual bool LogFatal(const char *msg) = 0;
|
||||
virtual bool LogSilent(const char *msg) = 0;
|
||||
|
||||
virtual bool LogF(const char *format, va_list args) = 0;
|
||||
virtual bool DebugLogF(const char *format, va_list args) = 0;
|
||||
virtual bool LogSilentF(const char *format, va_list args) = 0;
|
||||
|
||||
TestLog();
|
||||
|
||||
private:
|
||||
static TestLog *handler;
|
||||
|
||||
friend bool Log(const char*);
|
||||
friend bool DebugLog(const char*);
|
||||
friend bool LogFatal(const char*);
|
||||
friend bool LogSilent(const char*);
|
||||
friend bool LogF(const char*, ...);
|
||||
friend bool DebugLogF(const char*, ...);
|
||||
friend bool LogSilentF(const char*, ...);
|
||||
};
|
||||
|
||||
class LogMock : public TestLog
|
||||
{
|
||||
public:
|
||||
MOCK_METHOD1(Log, bool(const char*));
|
||||
MOCK_METHOD1(DebugLog, bool(const char*));
|
||||
MOCK_METHOD1(LogFatal, bool(const char*));
|
||||
MOCK_METHOD1(LogSilent, bool(const char*));
|
||||
MOCK_METHOD2(LogF, bool(const char*, va_list));
|
||||
MOCK_METHOD2(DebugLogF, bool(const char*, va_list));
|
||||
MOCK_METHOD2(LogSilentF, bool(const char*, va_list));
|
||||
};
|
|
@ -17,14 +17,24 @@
|
|||
|
||||
#include "C4Include.h"
|
||||
#include "AulTest.h"
|
||||
#include "TestLog.h"
|
||||
|
||||
#include "script/C4Aul.h"
|
||||
|
||||
class AulPredefFunctionTest : public AulTest
|
||||
{};
|
||||
|
||||
using ::testing::StartsWith;
|
||||
using ::testing::AnyNumber;
|
||||
using ::testing::_;
|
||||
|
||||
TEST_F(AulPredefFunctionTest, Translate)
|
||||
{
|
||||
// Expect the engine to warn when it can't find a translation
|
||||
LogMock log;
|
||||
EXPECT_CALL(log, DebugLogF(R"(WARNING: Translate: no translation for string "%s")", _));
|
||||
EXPECT_CALL(log, DebugLog(StartsWith(" by: "))).Times(AnyNumber()); // ignore stack trace
|
||||
|
||||
EXPECT_EQ(C4VString("a"), RunExpr("Translate(\"a\")"));
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue