Changeset View
Changeset View
Standalone View
Standalone View
source/third_party/ogre3d_preprocessor/tests/test_Preprocessor.h
Show All 15 Lines | |||||
*/ | */ | ||||
#include "lib/self_test.h" | #include "lib/self_test.h" | ||||
#include "graphics/PreprocessorWrapper.h" | #include "graphics/PreprocessorWrapper.h" | ||||
#include "ps/CStr.h" | #include "ps/CStr.h" | ||||
#include "third_party/ogre3d_preprocessor/OgreGLSLPreprocessor.h" | #include "third_party/ogre3d_preprocessor/OgreGLSLPreprocessor.h" | ||||
#include <cctype> | |||||
class TestPreprocessor : public CxxTest::TestSuite | class TestPreprocessor : public CxxTest::TestSuite | ||||
{ | { | ||||
public: | public: | ||||
void setUp() | void setUp() | ||||
{ | { | ||||
Ogre::CPreprocessor::ErrorHandler = CPreprocessorWrapper::PyrogenesisShaderError; | Ogre::CPreprocessor::ErrorHandler = CPreprocessorWrapper::PyrogenesisShaderError; | ||||
} | } | ||||
struct PreprocessorResult | struct PreprocessorResult | ||||
{ | { | ||||
CStr8 output; | CStr8 output; | ||||
CStr8 loggerOutput; | CStr8 loggerOutput; | ||||
}; | }; | ||||
// Replaces consecutive spaces/tabs by single space/tab. | |||||
CStr CompressWhiteSpaces(const CStr& source) | |||||
{ | |||||
CStr result; | |||||
for (char ch : source) | |||||
Stan: could be regexp to, probably slower though. | |||||
if (!std::isblank(ch) || (result.empty() || result.back() != ch)) | |||||
result += ch; | |||||
return result; | |||||
} | |||||
PreprocessorResult Parse(const char* in) | PreprocessorResult Parse(const char* in) | ||||
{ | { | ||||
PreprocessorResult result; | PreprocessorResult result; | ||||
TestLogger logger; | TestLogger logger; | ||||
Ogre::CPreprocessor preproc; | Ogre::CPreprocessor preproc; | ||||
size_t len = 0; | size_t len = 0; | ||||
char* out = preproc.Parse(in, strlen(in), len); | char* out = preproc.Parse(in, strlen(in), len); | ||||
result.output = std::string(out, len); | result.output = std::string(out, len); | ||||
result.loggerOutput = logger.GetOutput(); | result.loggerOutput = logger.GetOutput(); | ||||
// Free output if it's not inside the source string | // Free output if it's not inside the source string | ||||
if (!(out >= in && out < in + strlen(in))) | if (!(out >= in && out < in + strlen(in))) | ||||
free(out); | free(out); | ||||
return result; | return result; | ||||
} | } | ||||
PreprocessorResult ParseWithIncludes(const char* in, CPreprocessorWrapper::IncludeRetrieverCallback includeCallback) | |||||
{ | |||||
PreprocessorResult result; | |||||
TestLogger logger; | |||||
CPreprocessorWrapper preprocessor(includeCallback); | |||||
result.output = preprocessor.Preprocess(in); | |||||
result.loggerOutput = logger.GetOutput(); | |||||
return result; | |||||
} | |||||
void test_basic() | void test_basic() | ||||
{ | { | ||||
PreprocessorResult result = Parse("#define TEST 2\n1+1=TEST\n"); | PreprocessorResult result = Parse("#define TEST 2\n1+1=TEST\n"); | ||||
TS_ASSERT_EQUALS(result.output, "\n1+1=2\n"); | TS_ASSERT_EQUALS(result.output, "\n1+1=2\n"); | ||||
} | } | ||||
void test_error() | void test_error() | ||||
{ | { | ||||
▲ Show 20 Lines • Show All 45 Lines • ▼ Show 20 Lines | void test_division_by_zero_error() | ||||
PreprocessorResult result = Parse(R"( | PreprocessorResult result = Parse(R"( | ||||
#if 2 / 0 | #if 2 / 0 | ||||
42 | 42 | ||||
#endif | #endif | ||||
)"); | )"); | ||||
TS_ASSERT_EQUALS(result.output.Trim(PS_TRIM_BOTH), ""); | TS_ASSERT_EQUALS(result.output.Trim(PS_TRIM_BOTH), ""); | ||||
TS_ASSERT_STR_CONTAINS(result.loggerOutput, "ERROR: Preprocessor error: line 2: Division by zero"); | TS_ASSERT_STR_CONTAINS(result.loggerOutput, "ERROR: Preprocessor error: line 2: Division by zero"); | ||||
} | } | ||||
void test_include() | |||||
StanUnsubmitted Not Done Inline ActionsMaybe you load files from one of the test mods. Stan: Maybe you load files from one of the test mods. | |||||
{ | |||||
bool includeRetrieved = false; | |||||
CPreprocessorWrapper::IncludeRetrieverCallback includeCallback = [&includeRetrieved]( | |||||
const CStr& includePath, CStr& out) { | |||||
TS_ASSERT_EQUALS(includePath, "test.h"); | |||||
out = "42"; | |||||
includeRetrieved = true; | |||||
return true; | |||||
}; | |||||
PreprocessorResult result = ParseWithIncludes( | |||||
R"(#include "test.h" // Includes something.)", includeCallback); | |||||
TS_ASSERT(includeRetrieved); | |||||
TS_ASSERT_EQUALS(result.output.Trim(PS_TRIM_BOTH), "#line 1\n42\n#line 2"); | |||||
} | |||||
void test_include_double() | |||||
{ | |||||
CPreprocessorWrapper::IncludeRetrieverCallback includeCallback = []( | |||||
const CStr& includePath, CStr& out) { | |||||
TS_ASSERT_EQUALS(includePath, "test.h"); | |||||
out = "42"; | |||||
return true; | |||||
}; | |||||
PreprocessorResult result = ParseWithIncludes(R"( | |||||
#include "test.h" | |||||
#include "test.h" | |||||
#include "test.h" | |||||
)", includeCallback); | |||||
TS_ASSERT_EQUALS(result.output.Trim(PS_TRIM_BOTH), "#line 1\n42\n#line 3\n#line 1\n42\n#line 4\n#line 1\n42\n#line 5"); | |||||
} | |||||
void test_include_double_with_guards() | |||||
{ | |||||
CPreprocessorWrapper::IncludeRetrieverCallback includeCallback = []( | |||||
const CStr& includePath, CStr& out) { | |||||
TS_ASSERT_EQUALS(includePath, "test.h"); | |||||
out = R"(#ifndef INCLUDED_TEST | |||||
#define INCLUDED_TEST | |||||
42 | |||||
#endif)"; | |||||
return true; | |||||
}; | |||||
PreprocessorResult result = ParseWithIncludes(R"( | |||||
#include "test.h" | |||||
#include "test.h" | |||||
#include "test.h" | |||||
)", includeCallback); | |||||
TS_ASSERT_EQUALS(result.output.Trim(PS_TRIM_BOTH), "#line 1\n\n\t\t\t\t\n\t\t\t\t42\n\t\t\t\n#line 3\n#line 1\n\n\n\n\n#line 4\n#line 1\n\n\n\n\n#line 5"); | |||||
} | |||||
void test_include_invalid_argument() | |||||
{ | |||||
int includeRetrievedCounter = 0; | |||||
CPreprocessorWrapper::IncludeRetrieverCallback includeCallback = [&includeRetrievedCounter]( | |||||
const CStr& includePath, CStr& out) { | |||||
Not Done Inline ActionsIn file included from ../../../source/third_party/ogre3d_preprocessor/tests/test_Preprocessor.cpp:17: /home/user/0ad/source/third_party/ogre3d_preprocessor/tests/test_Preprocessor.h: In lambda function: /home/user/0ad/source/third_party/ogre3d_preprocessor/tests/test_Preprocessor.h:203:17: warning: unused parameter ‘includePath’ [-Wunused-parameter] 203 | const CStr& includePath, CStr& out) { | ~~~~~~~~~~~~^~~~~~~~~~~ /home/user/0ad/source/third_party/ogre3d_preprocessor/tests/test_Preprocessor.h: In lambda function: /home/user/0ad/source/third_party/ogre3d_preprocessor/tests/test_Preprocessor.h:220:17: warning: unused parameter ‘includePath’ [-Wunused-parameter] 220 | const CStr& includePath, CStr& out) { | ~~~~~~~~~~~~^~~~~~~~~~~ /home/user/0ad/source/third_party/ogre3d_preprocessor/tests/test_Preprocessor.h:220:36: warning: unused parameter ‘out’ [-Wunused-parameter] 220 | const CStr& includePath, CStr& out) { /home/user/0ad/source/third_party/ogre3d_preprocessor/tests/test_Preprocessor.h: In lambda function: /home/user/0ad/source/third_party/ogre3d_preprocessor/tests/test_Preprocessor.h:234:17: warning: unused parameter ‘includePath’ [-Wunused-parameter] 234 | const CStr& includePath, CStr& out) { | ~~~~~~~~~~~~^~~~~~~~~~~ Stan: ```lang=sh,lines=4
In file included from ../../.. | |||||
out = "42"; | |||||
++includeRetrievedCounter; | |||||
return true; | |||||
}; | |||||
PreprocessorResult result = ParseWithIncludes(R"( | |||||
#include <test.h> | |||||
#include test.h | |||||
)", includeCallback); | |||||
TS_ASSERT_EQUALS(includeRetrievedCounter, 0); | |||||
} | |||||
void test_include_invalid_file() | |||||
{ | |||||
CPreprocessorWrapper::IncludeRetrieverCallback includeCallback = []( | |||||
const CStr& includePath, CStr& out) { | |||||
return false; | |||||
}; | |||||
PreprocessorResult result = ParseWithIncludes(R"( | |||||
#include "missed_file.h" | |||||
)", includeCallback); | |||||
TS_ASSERT_STR_CONTAINS(result.loggerOutput, "ERROR: Preprocessor error: line 2: Can't load #include file: 'missed_file.h'"); | |||||
} | |||||
void test_include_with_defines() | |||||
{ | |||||
CPreprocessorWrapper::IncludeRetrieverCallback includeCallback = []( | |||||
const CStr& includePath, CStr& out) { | |||||
out = R"( | |||||
#if defined(A) | |||||
#define X 41 | |||||
#elif defined(B) | |||||
#define X 42 | |||||
#else | |||||
#define X 43 | |||||
#endif | |||||
#ifdef Y | |||||
#undef Y | |||||
#define Y 256 | |||||
#endif | |||||
vec3 color(); | |||||
)"; | |||||
return true; | |||||
}; | |||||
PreprocessorResult result = ParseWithIncludes(R"( | |||||
#define Y 128 | |||||
#define B 1 | |||||
#include "test.h" | |||||
X Y | |||||
)", includeCallback); | |||||
TS_ASSERT_EQUALS( | |||||
CompressWhiteSpaces(result.output.Trim(PS_TRIM_BOTH)), | |||||
"#line 1\n\n\t\n\n\n\t\n\t\n\n\n\t\n\t\n\t\n\t\n\tvec3 color();\n\t\n#line 5\n\t42 256"); | |||||
} | |||||
}; | }; | ||||
Not Done Inline ActionsJust for the record apparently (from the cxx docs) tests starting with x are also disabled (note that disabled tests are broken anyway). See D3119 Stan: Just for the record apparently (from the cxx docs) tests starting with x are also disabled… |
Wildfire Games · Phabricator
could be regexp to, probably slower though.