diff --git a/CMakeLists.txt b/CMakeLists.txt index 3f44584e73..25f603be06 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,111 +1,114 @@ cmake_minimum_required(VERSION 2.6) project(KDevPlatform) set(KDE4_BUILD_TESTS "ON" CACHE "BOOL" "Enable building of tests" FORCE ) set(CMAKE_MODULE_PATH ${KDevPlatform_SOURCE_DIR}/cmake/modules) set(KDEVPLATFORM_VERSION_MAJOR 1) set(KDEVPLATFORM_VERSION_MINOR 4) set(KDEVPLATFORM_VERSION_PATCH 60) set(KDE_MIN_VERSION "4.5.0") find_package(KDE4 4.5.0 REQUIRED) set(KDEVPLATFORM_LIB_VERSION 7.0.0) set(KDEVPLATFORM_LIB_SOVERSION 7) find_package(ZLIB REQUIRED) find_package(Grantlee 0.1.7 REQUIRED) +find_package(QJSON) +macro_log_feature( QJSON_FOUND "QJson" "QJson support for Uploading Patches to reviewboard" "http://qjson.sourceforge.net/" FALSE "0.7.0" "The qjson library is needed to enable uploading patches to reviewboard" ) include (KDE4Defaults) include (MacroWriteBasicCMakeVersionFile) include (MacroLibrary) # Make sure that we're having RPATH on our installed libs, else using kdevelop # from prefixes like $HOME/kdevelop breaks # Code taken from FindKDE4Internal.cmake for KDE 4.5 list(FIND CMAKE_PLATFORM_IMPLICIT_LINK_DIRECTORIES "${LIB_INSTALL_DIR}" _isSystemLibDir) if("${_isSystemLibDir}" STREQUAL "-1") set(CMAKE_INSTALL_RPATH "${LIB_INSTALL_DIR}") endif("${_isSystemLibDir}" STREQUAL "-1") set(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE) set(KOMPARE_FOUND FALSE) #macro_optional_find_package(Kompare) macro_bool_to_01(KOMPARE_FOUND HAVE_KOMPARE) #macro_log_feature(KOMPARE_FOUND "Kompare" "KPart to view file differences." # "http://www.caffeinated.me.uk/kompare/" FALSE "" # "Required for difference checking. From KDE SDK package, KDE 4.3.61 or higher needed.") add_definitions (${QT_DEFINITIONS} ${KDE4_DEFINITIONS}) add_definitions(-DQT_USE_FAST_CONCATENATION -DQT_USE_FAST_OPERATOR_PLUS -DQURL_NO_CAST_FROM_QSTRING) configure_file( ${CMAKE_CURRENT_SOURCE_DIR}/config-kdevplatform.h.cmake ${CMAKE_CURRENT_BINARY_DIR}/config-kdevplatform.h ) include_directories(${KDevPlatform_SOURCE_DIR} ${KDevPlatform_BINARY_DIR} ${KDE4_INCLUDES}) include_directories(${Grantlee_INCLUDE_DIRS}) # Now set the usual KDEVPLATFORM_XXX_LIBRARIES variable so we can more easily move plugins around set(KDEVPLATFORM_SUBLIME_LIBRARIES sublime) set(KDEVPLATFORM_INTERFACES_LIBRARIES kdevplatforminterfaces) set(KDEVPLATFORM_LANGUAGE_LIBRARIES kdevplatformlanguage) set(KDEVPLATFORM_PROJECT_LIBRARIES kdevplatformproject) set(KDEVPLATFORM_UTIL_LIBRARIES kdevplatformutil) set(KDEVPLATFORM_OUTPUTVIEW_LIBRARIES kdevplatformoutputview) set(KDEVPLATFORM_VCS_LIBRARIES kdevplatformvcs) set(KDEVPLATFORM_SHELL_LIBRARIES kdevplatformshell) set(KDEVPLATFORM_TESTS_LIBRARIES kdevplatformtests) +set(KDEVPLATFORM_JSONTESTS_LIBRARIES kdevplatformjsontests) set(KDEVPLATFORM_DEBUGGER_LIBRARIES kdevplatformdebugger) set(KDEVPLATFORM_DOCUMENTATION_LIBRARIES kdevplatformdocumentation) add_subdirectory(sublime) add_subdirectory(interfaces) add_subdirectory(project) add_subdirectory(language) add_subdirectory(shell) add_subdirectory(util) add_subdirectory(outputview) add_subdirectory(vcs) add_subdirectory(pics) #macro_optional_add_subdirectory(doc) add_subdirectory(debugger) add_subdirectory(documentation) add_subdirectory(template) add_subdirectory(tests) add_subdirectory(plugins) macro_write_basic_cmake_version_file( ${KDevPlatform_BINARY_DIR}/KDevPlatformConfigVersion.cmake ${KDEVPLATFORM_VERSION_MAJOR} ${KDEVPLATFORM_VERSION_MINOR} ${KDEVPLATFORM_VERSION_PATCH} ) configure_file( "${KDevPlatform_SOURCE_DIR}/KDevPlatformConfig.cmake.in" "${KDevPlatform_BINARY_DIR}/KDevPlatformConfig.cmake" @ONLY ) configure_file( "${KDevPlatform_SOURCE_DIR}/kdevplatformversion.h.cmake" "${KDevPlatform_BINARY_DIR}/kdevplatformversion.h" @ONLY ) if(KDE4_USE_COMMON_CMAKE_PACKAGE_CONFIG_DIR) set(_kdevplatform_CONFIG_DEST "${LIB_INSTALL_DIR}/cmake/kdevplatform") else(KDE4_USE_COMMON_CMAKE_PACKAGE_CONFIG_DIR) set(_kdevplatform_CONFIG_DEST "${LIB_INSTALL_DIR}/kdevplatform") endif(KDE4_USE_COMMON_CMAKE_PACKAGE_CONFIG_DIR) install( FILES "${KDevPlatform_BINARY_DIR}/kdevplatformversion.h" DESTINATION "${INCLUDE_INSTALL_DIR}/kdevplatform" ) install( FILES "${KDevPlatform_BINARY_DIR}/KDevPlatformConfig.cmake" "${KDevPlatform_BINARY_DIR}/KDevPlatformConfigVersion.cmake" DESTINATION "${_kdevplatform_CONFIG_DEST}" ) install( EXPORT KDevPlatformTargets DESTINATION "${_kdevplatform_CONFIG_DEST}" NAMESPACE KDevPlatformImport__ FILE KDevPlatformTargets.cmake ) # Put this last, so it can use _kdevplatform_CONFIG_DEST add_subdirectory(cmake) include(CTest) # CTestCustom.cmake has to be in the CTEST_BINARY_DIR. # in the KDE build system, this is the same as CMAKE_BINARY_DIR. configure_file(${CMAKE_SOURCE_DIR}/CTestCustom.cmake ${CMAKE_BINARY_DIR}/CTestCustom.cmake) diff --git a/KDevPlatformConfig.cmake.in b/KDevPlatformConfig.cmake.in index dfd16fcc90..afed48ff59 100644 --- a/KDevPlatformConfig.cmake.in +++ b/KDevPlatformConfig.cmake.in @@ -1,71 +1,74 @@ ######################################################################### # # KDevPlatform Configuration File # # This file sets various CMake Variables # # KDEVPLATFORM_INCLUDE_DIR - The Include Directory for all KDEVPLATFORM libraries # KDEVPLATFORM_INTERFACES_LIBRARIES - the interfaces library # KDEVPLATFORM_LANGUAGE_LIBRARIES - the language library # KDEVPLATFORM_OUTPUTVIEW_LIBRARIES - the outputview library # KDEVPLATFORM_PROJECT_LIBRARIES - the project library # KDEVPLATFORM_SUBLIME_LIBRARIES - the sublime library # KDEVPLATFORM_SHELL_LIBRARIES - the shell library # KDEVPLATFORM_TESTS_LIBRARIES - the tests library +# KDEVPLATFORM_JSONTESTS_LIBRARIES - the jsontests library # KDEVPLATFORM_UTIL_LIBRARIES - the util library # KDEVPLATFORM_VCS_LIBRARIES - the vcs library # KDEVPLATFORM_DEBUGGER_LIBRARIES - debugger module library # # Copyright 2008 Andreas Pakulat # Redistribution and use is allowed according to the terms of the BSD license. ###################################################################### get_filename_component(_KDEVPLATFORM_CURRENT_DIR "${CMAKE_CURRENT_LIST_FILE}" PATH) if(NOT WIN32) # This is needed on non-win32 platforms, as lib-install-dir might be in a # totally different prefix than include-install-dir. So instead hardcode the # absolute path during buildtime set( KDEVPLATFORM_INCLUDE_DIR "@INCLUDE_INSTALL_DIR@/kdevplatform" ) else(NOT WIN32) set( KDEVPLATFORM_INCLUDE_DIR "${_KDEVPLATFORM_CURRENT_DIR}/../../../include/kdevplatform" ) endif(NOT WIN32) if( NOT TARGET KDevPlatformImport__kdevplatforminterfaces ) include("${_KDEVPLATFORM_CURRENT_DIR}/KDevPlatformTargets.cmake") endif( NOT TARGET KDevPlatformImport__kdevplatforminterfaces ) macro( _kdevplatform_set_lib_vars _prefix _lib ) set( KDEVPLATFORM_${_prefix}_LIBRARIES KDevPlatformImport__${_lib} ) endmacro( _kdevplatform_set_lib_vars ) _kdevplatform_set_lib_vars( INTERFACES kdevplatforminterfaces ) _kdevplatform_set_lib_vars( PROJECT kdevplatformproject ) _kdevplatform_set_lib_vars( LANGUAGE kdevplatformlanguage ) _kdevplatform_set_lib_vars( UTIL kdevplatformutil ) _kdevplatform_set_lib_vars( SHELL kdevplatformshell ) _kdevplatform_set_lib_vars( SUBLIME sublime ) _kdevplatform_set_lib_vars( VCS kdevplatformvcs ) _kdevplatform_set_lib_vars( OUTPUTVIEW kdevplatformoutputview ) _kdevplatform_set_lib_vars( DEBUGGER kdevplatformdebugger ) _kdevplatform_set_lib_vars( DOCUMENTATION kdevplatformdocumentation ) _kdevplatform_set_lib_vars( TESTS kdevplatformtests ) +_kdevplatform_set_lib_vars( JSONTESTS kdevplatformjsontests ) include(${_KDEVPLATFORM_CURRENT_DIR}/KDevPlatformMacros.cmake) mark_as_advanced( KDEVPLATFORM_INTERFACES_LIBRARIES KDEVPLATFORM_LANGUAGE_LIBRARIES KDEVPLATFORM_OUTPUTVIEW_LIBRARIES KDEVPLATFORM_PROJECT_LIBRARIES KDEVPLATFORM_SUBLIME_LIBRARIES KDEVPLATFORM_SHELL_LIBRARIES KDEVPLATFORM_UTIL_LIBRARIES KDEVPLATFORM_VCS_LIBRARIES KDEVPLATFORM_DEBUGGER_LIBRARIES KDEVPLATFORM_DOCUMENTATION_LIBRARIES KDEVPLATFORM_TESTS_LIBRARIES + KDEVPLATFORM_JSONTESTS_LIBRARIES ) diff --git a/plugins/CMakeLists.txt b/plugins/CMakeLists.txt index 8aac3aef5c..40270cfa72 100644 --- a/plugins/CMakeLists.txt +++ b/plugins/CMakeLists.txt @@ -1,50 +1,48 @@ macro_optional_add_subdirectory(konsole) add_subdirectory(filemanager) add_subdirectory(appwizard) add_subdirectory(projectmanagerview) add_subdirectory(genericprojectmanager) add_subdirectory(standardoutputview) add_subdirectory(documentview) add_subdirectory(quickopen) add_subdirectory(executescript) add_subdirectory(contextbrowser) add_subdirectory(snippet) macro_optional_add_subdirectory(cvs) add_subdirectory(problemreporter) add_subdirectory(execute) add_subdirectory(externalscript) add_subdirectory(documentswitcher) add_subdirectory(patchreview) add_subdirectory(openwith) add_subdirectory(grepview) add_subdirectory(pastebin) add_subdirectory(codeutils) add_subdirectory(git) add_subdirectory(vcschangesview) add_subdirectory(templatemanager) add_subdirectory(filetemplates) add_subdirectory(testview) macro_optional_add_subdirectory(dashboard) set(Boost_ADDITIONAL_VERSIONS 1.39.0 1.39) find_package(Boost 1.35.0) macro_log_feature( Boost_FOUND "Boost" "Boost libraries for enabling the classbrowser" "http://www.boost.org" FALSE "1.35.0" "The boost libraries are needed to build the Class Browser" ) if(Boost_FOUND) macro_optional_add_subdirectory(classbrowser) endif(Boost_FOUND) find_package(SubversionLibrary) macro_log_feature( SUBVERSION_FOUND "Subversion" "Support for Subversion integration" "http://subversion.tigris.org" FALSE "1.3.0" "The subversion libraries are needed for the Subversion support" ) if(SUBVERSION_FOUND) macro_optional_add_subdirectory(subversion) endif(SUBVERSION_FOUND) -find_package(QJSON) -macro_log_feature( QJSON_FOUND "QJson" "QJson support for Uploading Patches to reviewboard" "http://qjson.sourceforge.net/" FALSE "0.7.0" "The qjson library is needed to enable uploading patches to reviewboard" ) if(QJSON_FOUND) macro_optional_add_subdirectory(reviewboard) endif(QJSON_FOUND) macro_display_feature_log() diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 4a306a48d1..987d7d0f9f 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -1,48 +1,52 @@ add_definitions( -DKDE_DEFAULT_DEBUG_AREA=9532 ) include_directories( ${KDevPlatform_SOURCE_DIR}/shell ) set(kdevplatformtests_LIB_SRCS kdevsignalspy.cpp testcore.cpp testproject.cpp testfile.cpp testlanguagecontroller.cpp testhelpers.cpp testplugincontroller.cpp ) kde4_add_library(kdevplatformtests SHARED ${kdevplatformtests_LIB_SRCS}) target_link_libraries(kdevplatformtests ${QT_QTCORE_LIBRARY} ${QT_QTTEST_LIBRARY} kdevplatformshell kdevplatformlanguage kdevplatformproject ) target_link_libraries(kdevplatformtests LINK_INTERFACE_LIBRARIES kdevplatformshell kdevplatformlanguage kdevplatformproject ) set_target_properties(kdevplatformtests PROPERTIES VERSION ${KDEVPLATFORM_LIB_VERSION} SOVERSION ${KDEVPLATFORM_LIB_SOVERSION} ) install(TARGETS kdevplatformtests EXPORT KDevPlatformTargets ${INSTALL_TARGETS_DEFAULT_ARGS} ) install(FILES autotestshell.h kdevsignalspy.h testcore.h testproject.h testfile.h testlanguagecontroller.h kdevplatformtestsexport.h testhelpers.h testplugincontroller.h DESTINATION ${INCLUDE_INSTALL_DIR}/kdevplatform/tests/ COMPONENT Devel ) + +if(QJSON_FOUND) + add_subdirectory(json) +endif(QJSON_FOUND) diff --git a/tests/json/CMakeLists.txt b/tests/json/CMakeLists.txt new file mode 100644 index 0000000000..6032125fad --- /dev/null +++ b/tests/json/CMakeLists.txt @@ -0,0 +1,31 @@ +include_directories( ${KDevPlatform_SOURCE_DIR}/shell ) + +set(kdevplatformjsontests_LIB_SRCS + delayedoutput.cpp + declarationvalidator.cpp +) + +kde4_add_library(kdevplatformjsontests SHARED ${kdevplatformjsontests_LIB_SRCS}) +target_link_libraries(kdevplatformjsontests + ${QT_QTCORE_LIBRARY} + ${QJSON_LIBRARIES} + kdevplatformlanguage +) +set_target_properties(kdevplatformjsontests PROPERTIES + VERSION ${KDEVPLATFORM_LIB_VERSION} + SOVERSION ${KDEVPLATFORM_LIB_SOVERSION} +) + +install(TARGETS kdevplatformjsontests EXPORT KDevPlatformTargets ${INSTALL_TARGETS_DEFAULT_ARGS} ) + +install(FILES + declarationvalidator.h + delayedoutput.h + jsontesthelpers.h + testsuite.h + jsondeclarationtests.h + jsonducontexttests.h + jsontypetests.h + DESTINATION ${INCLUDE_INSTALL_DIR}/kdevplatform/tests/json/ + COMPONENT Devel +) \ No newline at end of file diff --git a/tests/json/declarationvalidator.cpp b/tests/json/declarationvalidator.cpp new file mode 100644 index 0000000000..fb249343bf --- /dev/null +++ b/tests/json/declarationvalidator.cpp @@ -0,0 +1,79 @@ +/* This file is part of KDevelop + Copyright 2012 Olivier de Gaalon + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License version 2 as published by the Free Software Foundation. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ +#include +#include "language/duchain/declaration.h" +#include "declarationvalidator.h" +#include "testsuite.h" + +namespace KDevelop { + +class DeclarationValidatorPrivate +{ +public: + bool testsPassed; +}; + +QByteArray preprocess(QByteArray json) +{ + int commentIndex = json.indexOf('#', 0); + while (commentIndex > -1) + { + int commentEnd = json.indexOf('\n', commentIndex); + if (commentEnd == -1) + { + json.truncate(commentIndex); + break; + } + json.remove(commentIndex, commentEnd - commentIndex); + commentIndex = json.indexOf('#', commentIndex); + } + + return json.prepend('{').append('}'); +} + +DeclarationValidator::DeclarationValidator() +: d(new DeclarationValidatorPrivate) +{ +} +DeclarationValidator::~DeclarationValidator() +{ +} + +bool DeclarationValidator::testsPassed() +{ + return d->testsPassed; +} + +void DeclarationValidator::visit(DUContext*) { } +void DeclarationValidator::visit(Declaration* declaration) +{ + bool testDataOk; + QJson::Parser parser; + QVariantMap testData = parser.parse(preprocess(declaration->comment()), &testDataOk).toMap(); + if (!testDataOk) + { + d->testsPassed = false; + qDebug() << "Error parsing test data for declaration on line" << declaration->range().start.line + 1; + qDebug() << "Parser error on comment line" << parser.errorLine() << "was" << parser.errorString(); + return; + } + if (!KDevelop::runTests(testData, declaration)) + d->testsPassed = false; +} + +} \ No newline at end of file diff --git a/tests/json/declarationvalidator.h b/tests/json/declarationvalidator.h new file mode 100644 index 0000000000..2a1d971d5a --- /dev/null +++ b/tests/json/declarationvalidator.h @@ -0,0 +1,43 @@ +/* This file is part of KDevelop + Copyright 2012 Olivier de Gaalon + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License version 2 as published by the Free Software Foundation. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#ifndef DECLARATIONVALIDATOR_H +#define DECLARATIONVALIDATOR_H + +#include "language/duchain/ducontext.h" +#include "tests/kdevplatformtestsexport.h" + +namespace KDevelop { + +class DeclarationValidatorPrivate; +class KDEVPLATFORMTESTS_EXPORT DeclarationValidator : public DUChainVisitor +{ +public: + DeclarationValidator(); + virtual ~DeclarationValidator(); + + virtual bool testsPassed(); + virtual void visit(DUContext*); + virtual void visit(Declaration *declaration); +private: + Q_DISABLE_COPY(DeclarationValidator) + const QScopedPointer d; +}; + +} +#endif //DECLARATIONVALIDATOR_H \ No newline at end of file diff --git a/tests/json/delayedoutput.cpp b/tests/json/delayedoutput.cpp new file mode 100644 index 0000000000..1483d4f720 --- /dev/null +++ b/tests/json/delayedoutput.cpp @@ -0,0 +1,70 @@ +/* This file is part of KDevelop + Copyright 2012 Olivier de Gaalon + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License version 2 as published by the Free Software Foundation. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include + +#include "delayedoutput.h" + +namespace KDevelop +{ +typedef QPair DepthedOutput; + +class DelayedOutputPrivate +{ +public: + void flushOutput() + { + while (output.size()) + { + DepthedOutput curOutput = output.pop(); + qDebug().nospace() << qPrintable(QString(curOutput.second -1, ' ')) << curOutput.first.toUtf8().data(); + } + } + QStack output; + int delayDepth; +}; +DelayedOutput::Delay::Delay(DelayedOutput* output) +{ + m_output = output; + ++m_output->d->delayDepth; +} +DelayedOutput::Delay::~Delay() +{ + --m_output->d->delayDepth; + if (!m_output->d->delayDepth) + m_output->d->flushOutput(); +} + +DelayedOutput::DelayedOutput() +: d(new DelayedOutputPrivate()) +{ +} +DelayedOutput::~DelayedOutput() +{ +} +DelayedOutput& DelayedOutput::self() +{ + static DelayedOutput _inst; + return _inst; +} +void DelayedOutput::push(const QString& output) +{ + d->output.push(DepthedOutput(output, d->delayDepth)); +} + +} diff --git a/tests/json/delayedoutput.h b/tests/json/delayedoutput.h new file mode 100644 index 0000000000..8b3fea1749 --- /dev/null +++ b/tests/json/delayedoutput.h @@ -0,0 +1,54 @@ +/* This file is part of KDevelop + Copyright 2012 Olivier de Gaalon + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License version 2 as published by the Free Software Foundation. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#ifndef DELAYEDOUTPUT_H +#define DELAYEDOUTPUT_H + +#include +#include +#include "tests/kdevplatformtestsexport.h" + +namespace KDevelop +{ + +///Used to invert and visually nest error output generated by nested/recursive functions +///Used in TestSuite.h, use only at your own, singleton educated risk +class DelayedOutputPrivate; +class KDEVPLATFORMTESTS_EXPORT DelayedOutput +{ +public: + class Delay + { + public: + Delay(DelayedOutput* output); + ~Delay(); + private: + DelayedOutput *m_output; + }; + ~DelayedOutput(); + static DelayedOutput& self(); + void push(const QString &output); +private: + DelayedOutput(); + Q_DISABLE_COPY(DelayedOutput); + const QScopedPointer d; +}; + +} + +#endif //DELAYEDOUTPUT_H \ No newline at end of file diff --git a/tests/json/jsondeclarationtests.h b/tests/json/jsondeclarationtests.h new file mode 100644 index 0000000000..4fff1432b4 --- /dev/null +++ b/tests/json/jsondeclarationtests.h @@ -0,0 +1,141 @@ +/* This file is part of KDevelop + Copyright 2012 Olivier de Gaalon + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License version 2 as published by the Free Software Foundation. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#ifndef JSONDECLARATIONTESTS_H +#define JSONDECLARATIONTESTS_H + +#include "language/duchain/ducontext.h" +#include "language/duchain/declaration.h" +#include "language/duchain/indexeddeclaration.h" +#include "language/duchain/identifier.h" +#include "language/duchain/abstractfunctiondeclaration.h" +#include "language/duchain/types/typeutils.h" +#include "language/duchain/types/identifiedtype.h" +#include "jsontesthelpers.h" + +/** + * JSON Object Specification: + * DeclTestObject: Mapping of (string) declaration test names to values + * TypeTestObject: Mapping of (string) type test names to values + * CtxtTestObject: Mapping of (string) context test names to values + * + * Quick Reference: + * useCount : int + * identifier : string + * qualifiedIdentifier : string + * internalContext : CtxtTestObject + * internalFunctionContext : CtxtTestObject + * type : TypeTestObject + * unaliasedType : TypeTestObject + * targetType : TypeTestObject + * identifiedTypeQid : string + */ + +namespace KDevelop +{ + template<> + QString TestSuite::objectInformation(Declaration *decl) + { + return QString("(Declaration on line %1 in %2)") + .arg(decl->range().start.line + 1) + .arg(decl->topContext()->url().str()); + } + +namespace DeclarationTests +{ + +using namespace JsonTestHelpers; + +///JSON type: int +///@returns whether the declaration's number of uses matches the given value +DeclarationTest(useCount) +{ + return compareValues(decl->uses().size(), value, "Declaration's use count "); +} +///JSON type: string +///@returns whether the declaration's identifier matches the given value +DeclarationTest(identifier) +{ + return compareValues(decl->identifier().toString(), value, "Declaration's identifier"); +} +///JSON type: string +///@returns whether the declaration's qualified identifier matches the given value +DeclarationTest(qualifiedIdentifier) +{ + return compareValues(decl->qualifiedIdentifier().toString(), value, "Declaration's qualified identifier"); +} +///JSON type: CtxtTestObject +///@returns whether the tests for the declaration's internal context pass +DeclarationTest(internalContext) +{ + return testObject(decl->internalContext(), value, "Declaration's internal context"); +} +///JSON type: CtxtTestObject +///@returns whether the tests for the declaration's internal function context pass +DeclarationTest(internalFunctionContext) +{ + const QString NO_INTERNAL_CTXT = "%1 has no internal function context."; + AbstractFunctionDeclaration *absFuncDecl = dynamic_cast(decl); + if (!absFuncDecl || !absFuncDecl->internalFunctionContext()) + return NO_INTERNAL_CTXT.arg(decl->qualifiedIdentifier().toString()); + return testObject(decl->internalContext(), value, "Declaration's internal function context"); +} +/*FIXME: The type functions need some renaming and moving around + * Some (all?) functions from cpp's TypeUtils should be moved to the kdevplatform type utils + * targetType is exactly like realType except it also tosses pointers + * shortenTypeForViewing should go to type utils (and it's broken, it places const to the left of all *'s when it should be left or right of the type) + * UnaliasedType seems to be unable to understand aliases involving templates, perhaps a cpp version is in order + */ +///JSON type: TypeTestObject +///@returns whether the tests for the declaration's type pass +DeclarationTest(type) +{ + return testObject(decl->abstractType(), value, "Declaration's type"); +} +///JSON type: TypeTestObject +///@returns whether the tests for the declaration's unaliased type pass (TypeUtils::unaliasedType) +DeclarationTest(unaliasedType) +{ + return testObject(TypeUtils::unAliasedType(decl->abstractType()), value, "Declaration's unaliased type"); +} +///JSON type: TypeTestObject +///@returns whether the tests for the declaration's target type pass (TypeUtils::targetType) +DeclarationTest(targetType) +{ + return testObject(TypeUtils::targetType(decl->abstractType(), decl->topContext()), value, "Declaration's target type"); +} +///JSON type: string +///@returns whether the declaration's type's declaration can be identified and if it's qualified identifier matches the given value +DeclarationTest(identifiedTypeQid) +{ + VERIFY_TYPE(QString); + const QString UN_ID_ERROR = "Unable to identify declaration of type \"%1\"."; + AbstractType::Ptr type = decl->abstractType(); + IdentifiedType* idType = dynamic_cast(type.unsafeData()); + Declaration* idDecl = idType ? idType->declaration(decl->topContext()) : 0; + if (!idDecl) + return UN_ID_ERROR.arg(type->toString()); + + return compareValues(idDecl->qualifiedIdentifier().toString(), value, "Declaration's identified type"); +} + +} + +} + +#endif //JSONDECLARATIONTESTS_H diff --git a/tests/json/jsonducontexttests.h b/tests/json/jsonducontexttests.h new file mode 100644 index 0000000000..273b779fc1 --- /dev/null +++ b/tests/json/jsonducontexttests.h @@ -0,0 +1,76 @@ +/* This file is part of KDevelop + Copyright 2012 Olivier de Gaalon + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License version 2 as published by the Free Software Foundation. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#ifndef JSONDUCONTEXTTESTS_H +#define JSONDUCONTEXTTESTS_H + +#include "language/duchain/ducontext.h" +#include "jsontesthelpers.h" + +/** + * JSON Object Specification: + * FindDeclObject: Mapping of (string) search ids to DeclTestObjects + * + * Quick Reference: + * findDeclarations : FindDeclObject + * childCount : int + */ + +namespace KDevelop +{ + +namespace DUContextTests +{ + +using namespace JsonTestHelpers; + +///JSON type: FindDeclObject +///@returns whether each declaration can be found and passes its tests +ContextTest(findDeclarations) +{ + VERIFY_TYPE(QVariantMap); + QString INVALID_ERROR = "Attempted to test invalid context."; + QString NOT_FOUND_ERROR = "Could not find declaration \"%1\"."; + QString DECL_ERROR = "Declaration found with \"%1\" did not pass tests."; + if (!ctxt) + return INVALID_ERROR; + QVariantMap findDecls = value.toMap(); + for (QVariantMap::iterator it = findDecls.begin(); it != findDecls.end(); ++it) + { + QualifiedIdentifier searchId(it.key()); + QList ret = ctxt->findDeclarations(searchId, CursorInRevision::invalid()); + if (!ret.size()) + return NOT_FOUND_ERROR.arg(it.key()); + + if (!runTests(it.value().toMap(), ret.first())) + return DECL_ERROR.arg(it.key()); + } + return SUCCESS; +} +///JSON type: int +///@returns whether the number of child contexts matches the given value +ContextTest(childCount) +{ + return compareValues(ctxt->childContexts().size(), value, "Context's child count"); +} + +} + +} + +#endif //JSONDUCONTEXTTESTS_H diff --git a/tests/json/jsontesthelpers.h b/tests/json/jsontesthelpers.h new file mode 100644 index 0000000000..8f62f4a690 --- /dev/null +++ b/tests/json/jsontesthelpers.h @@ -0,0 +1,70 @@ +/* This file is part of KDevelop + Copyright 2012 Olivier de Gaalon + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License version 2 as published by the Free Software Foundation. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#ifndef JSONTESTHELPERS_H +#define JSONTESTHELPERS_H + +#include "testsuite.h" + +#define VERIFY_TYPE(type)\ +if (!value.canConvert())\ + return JsonTestHelpers::INVALID_JSON_TYPE + +#define __AddTest(testName, objType)\ +bool testName##Added = KDevelop::TestSuite::get().addTest(#testName, &testName) + +#define __DefineTest(testName, objType, objName)\ +QString testName(const QVariant&, objType);\ +__AddTest(testName, objType);\ +QString testName(const QVariant &value, objType objName) + +#define DeclarationTest(testName) __DefineTest(testName, KDevelop::Declaration*, decl) +#define TypeTest(testName) __DefineTest(testName, KDevelop::AbstractType::Ptr, type) +#define ContextTest(testName) __DefineTest(testName, KDevelop::DUContext*, ctxt) + +namespace KDevelop +{ + +namespace JsonTestHelpers +{ + +const QString SUCCESS = QString(); +const QString INVALID_JSON_TYPE = QString("Incorrect JSON type provided for test."); + +template +inline QString compareValues(Type realValue, const QVariant &value, const QString &errorDesc) +{ + VERIFY_TYPE(Type); + const QString ERROR = "%1 (\"%2\") doesn't match test data (\"%3\")."; + return realValue == value.value() ? + SUCCESS : ERROR.arg(errorDesc).arg(realValue).arg(value.value()); +} + +template +inline QString testObject(Object obj, const QVariant &value, const QString &errorDesc) +{ + VERIFY_TYPE(QVariantMap); + const QString ERROR = "%1 did not pass tests."; + return KDevelop::TestSuite::get().runTests(value.toMap(), obj) ? SUCCESS : ERROR.arg(errorDesc); +} + +} + +} + +#endif //JSONTESTHELPERS_H \ No newline at end of file diff --git a/tests/json/jsontypetests.h b/tests/json/jsontypetests.h new file mode 100644 index 0000000000..0f4492f4e8 --- /dev/null +++ b/tests/json/jsontypetests.h @@ -0,0 +1,73 @@ +/* This file is part of KDevelop + Copyright 2012 Olivier de Gaalon + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License version 2 as published by the Free Software Foundation. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#ifndef JSONTYPETESTS_H +#define JSONTYPETESTS_H + +#include "language/duchain/types/abstracttype.h" +#include "language/duchain/types/delayedtype.h" +#include "language/duchain/types/functiontype.h" +#include "jsontesthelpers.h" + +/** + * Quick Reference: + * findDeclarations : FindDeclObject + * childCount : int + */ + +namespace KDevelop +{ + +namespace TypeTests +{ + +using namespace JsonTestHelpers; + +///JSON type: string +///@returns whether the type toString matches the given value +TypeTest(toString) +{ + if (FunctionType::Ptr funcType = type.cast()) + type = funcType->returnType(); + + QString typeStr = type ? type->toString() : ""; + return compareValues(typeStr, value, "Type's toString"); +} +///JSON type: bool +///@returns whether type's constness matches the given value +TypeTest(isConst) +{ + VERIFY_TYPE(bool); + bool typeIsConst = false; + if (DelayedType::Ptr delayed = type.cast()) + typeIsConst = delayed->identifier().isConstant(); + else + typeIsConst = (type->modifiers() & AbstractType::ConstModifier); + + if (typeIsConst != value.toBool()) + return typeIsConst ? "Type is constant, but test data expects non-const." : + "Type is non-const, but test data expects constant."; + + return SUCCESS; +} + +} + +} + +#endif //JSONTYPETESTS_H \ No newline at end of file diff --git a/tests/json/testsuite.h b/tests/json/testsuite.h new file mode 100644 index 0000000000..51f5051677 --- /dev/null +++ b/tests/json/testsuite.h @@ -0,0 +1,105 @@ +/* This file is part of KDevelop + Copyright 2012 Olivier de Gaalon + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License version 2 as published by the Free Software Foundation. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#ifndef TESTSUITE_H +#define TESTSUITE_H + +#include +#include "delayedoutput.h" + +namespace KDevelop +{ + +const QString EXPECT_FAIL = "EXPECT_FAIL"; +const QString FAILED_TO_FAIL = "\"%1\" FAILED TO FAIL AS EXPECTED: \"%2\" %3"; +const QString EXPECTED_FAIL = "\"%1\" FAILED (expected): %2 %3"; +const QString FAIL = "\"%1\" FAILED: %2 %3"; +const QString TEST_NOT_FOUND = "Test not found"; + +template +class KDEVPLATFORMTESTS_EXPORT TestSuite +{ +public: + typedef QString (*TestFunction)(const QVariant&, T); + static TestSuite& get() + { + static TestSuite _inst; + return _inst; + }; + bool addTest(QString testName, TestFunction testFunc) + { + m_testFunctions.insert(testName, testFunc); + return true; + } + bool runTests(const QVariantMap &testData, T object) + { + QVariantMap expectedFails = expectedFailures(testData); + QVariantMap::const_iterator it; + DelayedOutput::Delay delay(&DelayedOutput::self()); + for (it = testData.begin(); it != testData.end(); ++it) + { + if (it.key() == EXPECT_FAIL) + continue; + + QString result = m_testFunctions.value(it.key(), &TestSuite::noSuchTest)(it.value(), object); + QString expectedFailure = expectedFails.value(it.key(), QString()).toString(); + + //Either ("expected failure" & "no result failure") or ("no expected failure" & "result failure") + if ((bool)expectedFailure.size() ^ (bool)result.size()) + { + DelayedOutput::self().push(result.size() ? FAIL.arg(it.key(), result, objectInformation(object)) : + FAILED_TO_FAIL.arg(it.key(), expectedFailure, objectInformation(object))); + return false; + } + + if (expectedFailure.size()) + qDebug() << EXPECTED_FAIL.arg(it.key(), expectedFailure, objectInformation(object)).toUtf8().data(); + } + return true; + } +private: + QVariantMap expectedFailures(const QVariantMap &testData) + { + if (!testData.contains(EXPECT_FAIL)) + return QVariantMap(); + + return testData[EXPECT_FAIL].toMap(); + } + static QString noSuchTest(const QVariant&, T) + { + return TEST_NOT_FOUND; + } + static QString objectInformation(T) + { + return QString(); + } + QHash m_testFunctions; + + TestSuite() { } + Q_DISABLE_COPY(TestSuite); +}; + +template +inline bool runTests(const QVariantMap &data, T object) +{ + return TestSuite::get().runTests(data, object); +} + +} + +#endif //TESTSUITE_H