mirror of
https://github.com/baldurk/renderdoc.git
synced 2026-05-05 01:20:42 +00:00
Add optional output file for qrenderdoc unit tests
This commit is contained in:
@@ -69,8 +69,8 @@ PyTypeObject **SbkPySide2_QtWidgetsTypes = NULL;
|
||||
#include "version.h"
|
||||
|
||||
// exported by generated files, used to check interface compliance
|
||||
bool CheckCoreInterface();
|
||||
bool CheckQtInterface();
|
||||
bool CheckCoreInterface(rdcstr &log);
|
||||
bool CheckQtInterface(rdcstr &log);
|
||||
|
||||
// defined in SWIG-generated renderdoc_python.cpp
|
||||
extern "C" PyObject *PyInit_renderdoc(void);
|
||||
@@ -457,13 +457,13 @@ PythonContext::~PythonContext()
|
||||
outputTick();
|
||||
}
|
||||
|
||||
bool PythonContext::CheckInterfaces()
|
||||
bool PythonContext::CheckInterfaces(rdcstr &log)
|
||||
{
|
||||
bool errors = false;
|
||||
|
||||
PyGILState_STATE gil = PyGILState_Ensure();
|
||||
errors |= CheckCoreInterface();
|
||||
errors |= CheckQtInterface();
|
||||
errors |= CheckCoreInterface(log);
|
||||
errors |= CheckQtInterface(log);
|
||||
PyGILState_Release(gil);
|
||||
|
||||
return errors;
|
||||
|
||||
@@ -61,7 +61,7 @@ public:
|
||||
rdcarray<rdcpair<rdcstr, PyObject *>> &args);
|
||||
static void FreePyArgs(rdcarray<rdcpair<rdcstr, PyObject *>> &args);
|
||||
|
||||
bool CheckInterfaces();
|
||||
bool CheckInterfaces(rdcstr &log);
|
||||
|
||||
QString versionString();
|
||||
|
||||
|
||||
@@ -43,7 +43,7 @@ enum class NameType
|
||||
Member,
|
||||
};
|
||||
|
||||
inline bool checkname(const char *baseType, rdcstr name, NameType nameType)
|
||||
inline bool checkname(rdcstr &log, const char *baseType, rdcstr name, NameType nameType)
|
||||
{
|
||||
// skip __ prefixed names
|
||||
if(name.beginsWith("__"))
|
||||
@@ -106,9 +106,9 @@ inline bool checkname(const char *baseType, rdcstr name, NameType nameType)
|
||||
|
||||
snprintf(convert_error, sizeof(convert_error) - 1,
|
||||
"Name of %s '%s.%s' does not match naming scheme.\n"
|
||||
"Should start with %s letter and not contain underscores",
|
||||
"Should start with %s letter and not contain underscores\n",
|
||||
nameTypeStr, baseType, name.c_str(), member ? "lowercase" : "uppercase");
|
||||
RENDERDOC_LogMessage(LogType::Error, "QTRD", __FILE__, __LINE__, convert_error);
|
||||
log += convert_error;
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -116,7 +116,7 @@ inline bool checkname(const char *baseType, rdcstr name, NameType nameType)
|
||||
return false;
|
||||
}
|
||||
|
||||
inline bool check_interface(swig_type_info **swig_types, size_t numTypes)
|
||||
inline bool check_interface(rdcstr &log, swig_type_info **swig_types, size_t numTypes)
|
||||
{
|
||||
// track all errors and fatal error at the end, so we see all of the problems at once instead of
|
||||
// requiring rebuilds over and over.
|
||||
@@ -142,13 +142,13 @@ inline bool check_interface(swig_type_info **swig_types, size_t numTypes)
|
||||
if(!result.second)
|
||||
{
|
||||
snprintf(convert_error, sizeof(convert_error) - 1,
|
||||
"Duplicate docstring '%s' found on struct '%s' - are you missing a DOCUMENT()?",
|
||||
"Duplicate docstring '%s' found on struct '%s' - are you missing a DOCUMENT()?\n",
|
||||
typedoc.c_str(), typeobj->tp_name);
|
||||
RENDERDOC_LogMessage(LogType::Error, "QTRD", __FILE__, __LINE__, convert_error);
|
||||
log += convert_error;
|
||||
errors_found = true;
|
||||
}
|
||||
|
||||
errors_found |= checkname("renderdoc", typeobj->tp_name, NameType::Type);
|
||||
errors_found |= checkname(log, "renderdoc", typeobj->tp_name, NameType::Type);
|
||||
|
||||
PyObject *dict = typeobj->tp_dict;
|
||||
|
||||
@@ -179,8 +179,9 @@ inline bool check_interface(swig_type_info **swig_types, size_t numTypes)
|
||||
if(str == NULL || len == 0)
|
||||
{
|
||||
snprintf(convert_error, sizeof(convert_error) - 1,
|
||||
"Couldn't get member name for %i'th member of '%s'", (int)i, typeobj->tp_name);
|
||||
RENDERDOC_LogMessage(LogType::Error, "QTRD", __FILE__, __LINE__, convert_error);
|
||||
"Couldn't get member name for %i'th member of '%s'\n", (int)i,
|
||||
typeobj->tp_name);
|
||||
log += convert_error;
|
||||
errors_found = true;
|
||||
}
|
||||
else
|
||||
@@ -198,7 +199,7 @@ inline bool check_interface(swig_type_info **swig_types, size_t numTypes)
|
||||
|
||||
// if it's a callable it's a method, ignore it
|
||||
if(!PyCallable_Check(value) && !PyType_IsSubtype(value->ob_type, &PyStaticMethod_Type))
|
||||
errors_found |= checkname(typeobj->tp_name, name, nameType);
|
||||
errors_found |= checkname(log, typeobj->tp_name, name, nameType);
|
||||
}
|
||||
|
||||
Py_DecRef(bytes);
|
||||
@@ -241,9 +242,9 @@ inline bool check_interface(swig_type_info **swig_types, size_t numTypes)
|
||||
if(documented.find(*it) == documented.end())
|
||||
{
|
||||
snprintf(convert_error, sizeof(convert_error) - 1,
|
||||
"'%s::%s' is not documented in class docstring", typeobj->tp_name,
|
||||
"'%s::%s' is not documented in class docstring\n", typeobj->tp_name,
|
||||
it->c_str());
|
||||
RENDERDOC_LogMessage(LogType::Error, "QTRD", __FILE__, __LINE__, convert_error);
|
||||
log += convert_error;
|
||||
errors_found = true;
|
||||
}
|
||||
}
|
||||
@@ -257,7 +258,7 @@ inline bool check_interface(swig_type_info **swig_types, size_t numTypes)
|
||||
{
|
||||
rdcstr method_doc = method->ml_doc;
|
||||
|
||||
errors_found |= checkname(typeobj->tp_name, method->ml_name, NameType::Method);
|
||||
errors_found |= checkname(log, typeobj->tp_name, method->ml_name, NameType::Method);
|
||||
|
||||
int32_t i = 0;
|
||||
while(method_doc[i] == '\n')
|
||||
@@ -278,9 +279,9 @@ inline bool check_interface(swig_type_info **swig_types, size_t numTypes)
|
||||
{
|
||||
snprintf(
|
||||
convert_error, sizeof(convert_error) - 1,
|
||||
"Duplicate docstring '%s' found on method '%s.%s' - are you missing a DOCUMENT()?",
|
||||
"Duplicate docstring '%s' found on method '%s.%s' - are you missing a DOCUMENT()?\n",
|
||||
method_doc.c_str(), typeobj->tp_name, method->ml_name);
|
||||
RENDERDOC_LogMessage(LogType::Error, "QTRD", __FILE__, __LINE__, convert_error);
|
||||
log += convert_error;
|
||||
errors_found = true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -120,7 +120,7 @@ TEMPLATE_ARRAY_INSTANTIATE_PTR(rdcarray, ICaptureViewer)
|
||||
static swig_type_info **interfaceCheckTypes;
|
||||
static size_t interfaceCheckNumTypes = 0;
|
||||
|
||||
bool CheckQtInterface()
|
||||
bool CheckQtInterface(rdcstr &log)
|
||||
{
|
||||
#if defined(RELEASE)
|
||||
return false;
|
||||
@@ -128,7 +128,7 @@ TEMPLATE_ARRAY_INSTANTIATE_PTR(rdcarray, ICaptureViewer)
|
||||
if(interfaceCheckNumTypes == 0)
|
||||
return false;
|
||||
|
||||
return check_interface(interfaceCheckTypes, interfaceCheckNumTypes);
|
||||
return check_interface(log, interfaceCheckTypes, interfaceCheckNumTypes);
|
||||
#endif
|
||||
}
|
||||
%}
|
||||
|
||||
@@ -489,7 +489,7 @@ extern "C" PyObject *RENDERDOC_DumpObject(PyObject *obj)
|
||||
static swig_type_info **interfaceCheckTypes;
|
||||
static size_t interfaceCheckNumTypes = 0;
|
||||
|
||||
bool CheckCoreInterface()
|
||||
bool CheckCoreInterface(rdcstr &log)
|
||||
{
|
||||
#if defined(RELEASE)
|
||||
return false;
|
||||
@@ -497,7 +497,7 @@ extern "C" PyObject *RENDERDOC_DumpObject(PyObject *obj)
|
||||
if(interfaceCheckNumTypes == 0)
|
||||
return false;
|
||||
|
||||
return check_interface(interfaceCheckTypes, interfaceCheckNumTypes);
|
||||
return check_interface(log, interfaceCheckTypes, interfaceCheckNumTypes);
|
||||
#endif
|
||||
}
|
||||
%}
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
* THE SOFTWARE.
|
||||
******************************************************************************/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <QApplication>
|
||||
#include <QCommandLineParser>
|
||||
#include <QDir>
|
||||
@@ -104,21 +105,35 @@ int main(int argc, char *argv[])
|
||||
|
||||
bool errors = false;
|
||||
|
||||
qInfo() << "Checking python binding consistency.";
|
||||
FILE *logOut = NULL;
|
||||
|
||||
if(argc >= 3)
|
||||
logOut = fopen(argv[2], "w");
|
||||
|
||||
if(logOut == NULL)
|
||||
logOut = stdout;
|
||||
|
||||
fputs("Checking python binding consistency.\n", logOut);
|
||||
|
||||
rdcstr errorLog;
|
||||
|
||||
{
|
||||
PythonContextHandle py;
|
||||
errors = py.ctx().CheckInterfaces();
|
||||
errors = py.ctx().CheckInterfaces(errorLog);
|
||||
}
|
||||
|
||||
if(errors)
|
||||
{
|
||||
qCritical() << "Found errors in python bindings. Please fix!";
|
||||
RENDERDOC_LogMessage(LogType::Error, "EXTN", __FILE__, __LINE__, errorLog.c_str());
|
||||
fputs("Found errors in python bindings. Please fix!\n", logOut);
|
||||
fputs(errorLog.c_str(), logOut);
|
||||
return 1;
|
||||
}
|
||||
|
||||
qInfo() << "Python bindings are consistent.";
|
||||
return 0;
|
||||
else
|
||||
{
|
||||
fputs("Python bindings are consistent.\n", logOut);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
Reference in New Issue
Block a user