From bc1b724476db3f7d52ad135857b693487644611f Mon Sep 17 00:00:00 2001 From: Christian Kamm Date: Mon, 14 Nov 2011 15:08:25 +0100 Subject: C++: Move codegen test into the CppTools plugin. Change-Id: I4c70a9dbd5445188c3d202427da96e1c6ff90b63 Reviewed-by: Bill King --- src/plugins/cpptools/cppcodegen_test.cpp | 636 +++++++++++++++++++++++++ src/plugins/cpptools/cpptools.pro | 5 + src/plugins/cpptools/cpptoolsplugin.h | 15 + tests/auto/cplusplus/codegen/codegen.pro | 5 - tests/auto/cplusplus/codegen/tst_codegen.cpp | 681 --------------------------- tests/auto/cplusplus/cplusplus.pro | 1 - 6 files changed, 656 insertions(+), 687 deletions(-) create mode 100644 src/plugins/cpptools/cppcodegen_test.cpp delete mode 100644 tests/auto/cplusplus/codegen/codegen.pro delete mode 100644 tests/auto/cplusplus/codegen/tst_codegen.cpp diff --git a/src/plugins/cpptools/cppcodegen_test.cpp b/src/plugins/cpptools/cppcodegen_test.cpp new file mode 100644 index 0000000000..3bbdaf1e30 --- /dev/null +++ b/src/plugins/cpptools/cppcodegen_test.cpp @@ -0,0 +1,636 @@ +/************************************************************************** +** +** This file is part of Qt Creator +** +** Copyright (c) 2011 Nokia Corporation and/or its subsidiary(-ies). +** +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** +** GNU Lesser General Public License Usage +** +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this file. +** Please review the following information to ensure the GNU Lesser General +** Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** Other Usage +** +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +**************************************************************************/ + +#include "cpptoolsplugin.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +/*! + Tests for various parts of the code generation. Well, okay, currently it only + tests the InsertionPointLocator. + */ +using namespace CPlusPlus; +using namespace CppTools; +using namespace CppTools::Internal; + +/*! + Should insert at line 3, column 1, with "public:\n" as prefix and without suffix. + */ +void CppToolsPlugin::test_codegen_public_in_empty_class() +{ + const QByteArray src = "\n" + "class Foo\n" // line 1 + "{\n" + "};\n" + "\n"; + + Document::Ptr doc = Document::create("public_in_empty_class"); + doc->setSource(src); + doc->parse(); + doc->check(); + + QCOMPARE(doc->diagnosticMessages().size(), 0); + QCOMPARE(doc->globalSymbolCount(), 1U); + + Class *foo = doc->globalSymbolAt(0)->asClass(); + QVERIFY(foo); + QCOMPARE(foo->line(), 1U); + QCOMPARE(foo->column(), 7U); + + Snapshot snapshot; + snapshot.insert(doc); + CppRefactoringChanges changes(snapshot); + InsertionPointLocator find(changes); + InsertionLocation loc = find.methodDeclarationInClass( + doc->fileName(), + foo, + InsertionPointLocator::Public); + QVERIFY(loc.isValid()); + QCOMPARE(loc.prefix(), QLatin1String("public:\n")); + QVERIFY(loc.suffix().isEmpty()); + QCOMPARE(loc.line(), 3U); + QCOMPARE(loc.column(), 1U); +} + +/*! + Should insert at line 3, column 1, without prefix and without suffix. + */ +void CppToolsPlugin::test_codegen_public_in_nonempty_class() +{ + const QByteArray src = "\n" + "class Foo\n" // line 1 + "{\n" + "public:\n" // line 3 + "};\n" // line 4 + "\n"; + + Document::Ptr doc = Document::create("public_in_nonempty_class"); + doc->setSource(src); + doc->parse(); + doc->check(); + + QCOMPARE(doc->diagnosticMessages().size(), 0); + QCOMPARE(doc->globalSymbolCount(), 1U); + + Class *foo = doc->globalSymbolAt(0)->asClass(); + QVERIFY(foo); + QCOMPARE(foo->line(), 1U); + QCOMPARE(foo->column(), 7U); + + Snapshot snapshot; + snapshot.insert(doc); + CppRefactoringChanges changes(snapshot); + InsertionPointLocator find(changes); + InsertionLocation loc = find.methodDeclarationInClass( + doc->fileName(), + foo, + InsertionPointLocator::Public); + QVERIFY(loc.isValid()); + QVERIFY(loc.prefix().isEmpty()); + QVERIFY(loc.suffix().isEmpty()); + QCOMPARE(loc.line(), 4U); + QCOMPARE(loc.column(), 1U); +} + +/*! + Should insert at line 3, column 1, with "public:\n" as prefix and "\n suffix. + */ +void CppToolsPlugin::test_codegen_public_before_protected() +{ + const QByteArray src = "\n" + "class Foo\n" // line 1 + "{\n" + "protected:\n" // line 3 + "};\n" + "\n"; + + Document::Ptr doc = Document::create("public_before_protected"); + doc->setSource(src); + doc->parse(); + doc->check(); + + QCOMPARE(doc->diagnosticMessages().size(), 0); + QCOMPARE(doc->globalSymbolCount(), 1U); + + Class *foo = doc->globalSymbolAt(0)->asClass(); + QVERIFY(foo); + QCOMPARE(foo->line(), 1U); + QCOMPARE(foo->column(), 7U); + + Snapshot snapshot; + snapshot.insert(doc); + CppRefactoringChanges changes(snapshot); + InsertionPointLocator find(changes); + InsertionLocation loc = find.methodDeclarationInClass( + doc->fileName(), + foo, + InsertionPointLocator::Public); + QVERIFY(loc.isValid()); + QCOMPARE(loc.prefix(), QLatin1String("public:\n")); + QCOMPARE(loc.suffix(), QLatin1String("\n")); + QCOMPARE(loc.column(), 1U); + QCOMPARE(loc.line(), 3U); +} + +/*! + Should insert at line 4, column 1, with "private:\n" as prefix and without + suffix. + */ +void CppToolsPlugin::test_codegen_private_after_protected() +{ + const QByteArray src = "\n" + "class Foo\n" // line 1 + "{\n" + "protected:\n" // line 3 + "};\n" + "\n"; + + Document::Ptr doc = Document::create("private_after_protected"); + doc->setSource(src); + doc->parse(); + doc->check(); + + QCOMPARE(doc->diagnosticMessages().size(), 0); + QCOMPARE(doc->globalSymbolCount(), 1U); + + Class *foo = doc->globalSymbolAt(0)->asClass(); + QVERIFY(foo); + QCOMPARE(foo->line(), 1U); + QCOMPARE(foo->column(), 7U); + + Snapshot snapshot; + snapshot.insert(doc); + CppRefactoringChanges changes(snapshot); + InsertionPointLocator find(changes); + InsertionLocation loc = find.methodDeclarationInClass( + doc->fileName(), + foo, + InsertionPointLocator::Private); + QVERIFY(loc.isValid()); + QCOMPARE(loc.prefix(), QLatin1String("private:\n")); + QVERIFY(loc.suffix().isEmpty()); + QCOMPARE(loc.column(), 1U); + QCOMPARE(loc.line(), 4U); +} + +/*! + Should insert at line 4, column 1, with "protected:\n" as prefix and without + suffix. + */ +void CppToolsPlugin::test_codegen_protected_in_nonempty_class() +{ + const QByteArray src = "\n" + "class Foo\n" // line 1 + "{\n" + "public:\n" // line 3 + "};\n" // line 4 + "\n"; + + Document::Ptr doc = Document::create("protected_in_nonempty_class"); + doc->setSource(src); + doc->parse(); + doc->check(); + + QCOMPARE(doc->diagnosticMessages().size(), 0); + QCOMPARE(doc->globalSymbolCount(), 1U); + + Class *foo = doc->globalSymbolAt(0)->asClass(); + QVERIFY(foo); + QCOMPARE(foo->line(), 1U); + QCOMPARE(foo->column(), 7U); + + Snapshot snapshot; + snapshot.insert(doc); + CppRefactoringChanges changes(snapshot); + InsertionPointLocator find(changes); + InsertionLocation loc = find.methodDeclarationInClass( + doc->fileName(), + foo, + InsertionPointLocator::Protected); + QVERIFY(loc.isValid()); + QCOMPARE(loc.prefix(), QLatin1String("protected:\n")); + QVERIFY(loc.suffix().isEmpty()); + QCOMPARE(loc.column(), 1U); + QCOMPARE(loc.line(), 4U); +} + +/*! + Should insert at line 4, column 1, with "protected\n" as prefix and "\n" suffix. + */ +void CppToolsPlugin::test_codegen_protected_between_public_and_private() +{ + const QByteArray src = "\n" + "class Foo\n" // line 1 + "{\n" + "public:\n" // line 3 + "private:\n" // line 4 + "};\n" // line 5 + "\n"; + + Document::Ptr doc = Document::create("protected_betwee_public_and_private"); + doc->setSource(src); + doc->parse(); + doc->check(); + + QCOMPARE(doc->diagnosticMessages().size(), 0); + QCOMPARE(doc->globalSymbolCount(), 1U); + + Class *foo = doc->globalSymbolAt(0)->asClass(); + QVERIFY(foo); + QCOMPARE(foo->line(), 1U); + QCOMPARE(foo->column(), 7U); + + Snapshot snapshot; + snapshot.insert(doc); + CppRefactoringChanges changes(snapshot); + InsertionPointLocator find(changes); + InsertionLocation loc = find.methodDeclarationInClass( + doc->fileName(), + foo, + InsertionPointLocator::Protected); + QVERIFY(loc.isValid()); + QCOMPARE(loc.prefix(), QLatin1String("protected:\n")); + QCOMPARE(loc.suffix(), QLatin1String("\n")); + QCOMPARE(loc.column(), 1U); + QCOMPARE(loc.line(), 4U); +} + +/*! + Should insert at line 18, column 1, with "private slots:\n" as prefix and "\n" + as suffix. + + This is the typical Qt Designer case, with test-input like what the integration + generates. + */ +void CppToolsPlugin::test_codegen_qtdesigner_integration() +{ + const QByteArray src = "/**** Some long (C)opyright notice ****/\n" + "#ifndef MAINWINDOW_H\n" + "#define MAINWINDOW_H\n" + "\n" + "#include \n" + "\n" + "namespace Ui {\n" + " class MainWindow;\n" + "}\n" + "\n" + "class MainWindow : public QMainWindow\n" // line 10 + "{\n" + " Q_OBJECT\n" + "\n" + "public:\n" // line 14 + " explicit MainWindow(QWidget *parent = 0);\n" + " ~MainWindow();\n" + "\n" + "private:\n" // line 18 + " Ui::MainWindow *ui;\n" + "};\n" + "\n" + "#endif // MAINWINDOW_H\n"; + + Document::Ptr doc = Document::create("qtdesigner_integration"); + doc->setSource(src); + doc->parse(); + doc->check(); + + QCOMPARE(doc->diagnosticMessages().size(), 0); + QCOMPARE(doc->globalSymbolCount(), 2U); + + Class *foo = doc->globalSymbolAt(1)->asClass(); + QVERIFY(foo); + QCOMPARE(foo->line(), 10U); + QCOMPARE(foo->column(), 7U); + + Snapshot snapshot; + snapshot.insert(doc); + CppRefactoringChanges changes(snapshot); + InsertionPointLocator find(changes); + InsertionLocation loc = find.methodDeclarationInClass( + doc->fileName(), + foo, + InsertionPointLocator::PrivateSlot); + QVERIFY(loc.isValid()); + QCOMPARE(loc.prefix(), QLatin1String("private slots:\n")); + QCOMPARE(loc.suffix(), QLatin1String("\n")); + QCOMPARE(loc.line(), 18U); + QCOMPARE(loc.column(), 1U); +} + +void CppToolsPlugin::test_codegen_definition_empty_class() +{ + const QByteArray srcText = "\n" + "class Foo\n" // line 1 + "{\n" + "void foo();\n" // line 3 + "};\n" + "\n"; + + const QByteArray dstText = "\n" + "int x;\n" // line 1 + "\n"; + + Document::Ptr src = Document::create(QDir::tempPath() + QLatin1String("/file.h")); + Utils::FileSaver srcSaver(src->fileName()); + srcSaver.write(srcText); + srcSaver.finalize(); + src->setSource(srcText); + src->parse(); + src->check(); + QCOMPARE(src->diagnosticMessages().size(), 0); + QCOMPARE(src->globalSymbolCount(), 1U); + + Document::Ptr dst = Document::create(QDir::tempPath() + QLatin1String("/file.cpp")); + Utils::FileSaver dstSaver(dst->fileName()); + dstSaver.write(dstText); + dstSaver.finalize(); + dst->setSource(dstText); + dst->parse(); + dst->check(); + QCOMPARE(dst->diagnosticMessages().size(), 0); + QCOMPARE(dst->globalSymbolCount(), 1U); + + Snapshot snapshot; + snapshot.insert(src); + snapshot.insert(dst); + + Class *foo = src->globalSymbolAt(0)->asClass(); + QVERIFY(foo); + QCOMPARE(foo->line(), 1U); + QCOMPARE(foo->column(), 7U); + QCOMPARE(foo->memberCount(), 1U); + Declaration *decl = foo->memberAt(0)->asDeclaration(); + QVERIFY(decl); + QCOMPARE(decl->line(), 3U); + QCOMPARE(decl->column(), 6U); + + CppRefactoringChanges changes(snapshot); + InsertionPointLocator find(changes); + QList locList = find.methodDefinition(decl); + QVERIFY(locList.size() == 1); + InsertionLocation loc = locList.first(); + QCOMPARE(loc.fileName(), dst->fileName()); + QCOMPARE(loc.prefix(), QLatin1String("\n\n")); + QCOMPARE(loc.suffix(), QString()); + QCOMPARE(loc.line(), 1U); + QCOMPARE(loc.column(), 7U); +} + +void CppToolsPlugin::test_codegen_definition_first_member() +{ + const QByteArray srcText = "\n" + "class Foo\n" // line 1 + "{\n" + "void foo();\n" // line 3 + "void bar();\n" // line 4 + "};\n" + "\n"; + + const QByteArray dstText = QString( + "\n" + "#include \"%1/file.h\"\n" // line 1 + "int x;\n" + "\n" + "void Foo::bar()\n" // line 4 + "{\n" + "\n" + "}\n" + "\n" + "int y;\n").arg(QDir::tempPath()).toLatin1(); + + Document::Ptr src = Document::create(QDir::tempPath() + QLatin1String("/file.h")); + Utils::FileSaver srcSaver(src->fileName()); + srcSaver.write(srcText); + srcSaver.finalize(); + src->setSource(srcText); + src->parse(); + src->check(); + QCOMPARE(src->diagnosticMessages().size(), 0); + QCOMPARE(src->globalSymbolCount(), 1U); + + Document::Ptr dst = Document::create(QDir::tempPath() + QLatin1String("/file.cpp")); + dst->addIncludeFile(src->fileName(), 1); + Utils::FileSaver dstSaver(dst->fileName()); + dstSaver.write(dstText); + dstSaver.finalize(); + dst->setSource(dstText); + dst->parse(); + dst->check(); + QCOMPARE(dst->diagnosticMessages().size(), 0); + QCOMPARE(dst->globalSymbolCount(), 3U); + + Snapshot snapshot; + snapshot.insert(src); + snapshot.insert(dst); + + Class *foo = src->globalSymbolAt(0)->asClass(); + QVERIFY(foo); + QCOMPARE(foo->line(), 1U); + QCOMPARE(foo->column(), 7U); + QCOMPARE(foo->memberCount(), 2U); + Declaration *decl = foo->memberAt(0)->asDeclaration(); + QVERIFY(decl); + QCOMPARE(decl->line(), 3U); + QCOMPARE(decl->column(), 6U); + + CppRefactoringChanges changes(snapshot); + InsertionPointLocator find(changes); + QList locList = find.methodDefinition(decl); + QVERIFY(locList.size() == 1); + InsertionLocation loc = locList.first(); + QCOMPARE(loc.fileName(), dst->fileName()); + QCOMPARE(loc.line(), 4U); + QCOMPARE(loc.column(), 1U); + QCOMPARE(loc.suffix(), QLatin1String("\n\n")); + QCOMPARE(loc.prefix(), QString()); +} + +void CppToolsPlugin::test_codegen_definition_last_member() +{ + const QByteArray srcText = "\n" + "class Foo\n" // line 1 + "{\n" + "void foo();\n" // line 3 + "void bar();\n" // line 4 + "};\n" + "\n"; + + const QByteArray dstText = QString( + "\n" + "#include \"%1/file.h\"\n" // line 1 + "int x;\n" + "\n" + "void Foo::foo()\n" // line 4 + "{\n" + "\n" + "}\n" // line 7 + "\n" + "int y;\n").arg(QDir::tempPath()).toLatin1(); + + Document::Ptr src = Document::create(QDir::tempPath() + QLatin1String("/file.h")); + Utils::FileSaver srcSaver(src->fileName()); + srcSaver.write(srcText); + srcSaver.finalize(); + src->setSource(srcText); + src->parse(); + src->check(); + QCOMPARE(src->diagnosticMessages().size(), 0); + QCOMPARE(src->globalSymbolCount(), 1U); + + Document::Ptr dst = Document::create(QDir::tempPath() + QLatin1String("/file.cpp")); + dst->addIncludeFile(src->fileName(), 1); + Utils::FileSaver dstSaver(dst->fileName()); + dstSaver.write(dstText); + dstSaver.finalize(); + dst->setSource(dstText); + dst->parse(); + dst->check(); + QCOMPARE(dst->diagnosticMessages().size(), 0); + QCOMPARE(dst->globalSymbolCount(), 3U); + + Snapshot snapshot; + snapshot.insert(src); + snapshot.insert(dst); + + Class *foo = src->globalSymbolAt(0)->asClass(); + QVERIFY(foo); + QCOMPARE(foo->line(), 1U); + QCOMPARE(foo->column(), 7U); + QCOMPARE(foo->memberCount(), 2U); + Declaration *decl = foo->memberAt(1)->asDeclaration(); + QVERIFY(decl); + QCOMPARE(decl->line(), 4U); + QCOMPARE(decl->column(), 6U); + + CppRefactoringChanges changes(snapshot); + InsertionPointLocator find(changes); + QList locList = find.methodDefinition(decl); + QVERIFY(locList.size() == 1); + InsertionLocation loc = locList.first(); + QCOMPARE(loc.fileName(), dst->fileName()); + QCOMPARE(loc.line(), 7U); + QCOMPARE(loc.column(), 2U); + QCOMPARE(loc.prefix(), QLatin1String("\n\n")); + QCOMPARE(loc.suffix(), QString()); +} + +void CppToolsPlugin::test_codegen_definition_middle_member() +{ + const QByteArray srcText = "\n" + "class Foo\n" // line 1 + "{\n" + "void foo();\n" // line 3 + "void bar();\n" // line 4 + "void car();\n" // line 5 + "};\n" + "\n"; + + const QByteArray dstText = QString( + "\n" + "#include \"%1/file.h\"\n" // line 1 + "int x;\n" + "\n" + "void Foo::foo()\n" // line 4 + "{\n" + "\n" + "}\n" // line 7 + "\n" + "void Foo::car()\n" // line 9 + "{\n" + "\n" + "}\n" + "\n" + "int y;\n").arg(QDir::tempPath()).toLatin1(); + + Document::Ptr src = Document::create(QDir::tempPath() + QLatin1String("/file.h")); + Utils::FileSaver srcSaver(src->fileName()); + srcSaver.write(srcText); + srcSaver.finalize(); + src->setSource(srcText); + src->parse(); + src->check(); + QCOMPARE(src->diagnosticMessages().size(), 0); + QCOMPARE(src->globalSymbolCount(), 1U); + + Document::Ptr dst = Document::create(QDir::tempPath() + QLatin1String("/file.cpp")); + dst->addIncludeFile(src->fileName(), 1); + Utils::FileSaver dstSaver(dst->fileName()); + dstSaver.write(dstText); + dstSaver.finalize(); + dst->setSource(dstText); + dst->parse(); + dst->check(); + QCOMPARE(dst->diagnosticMessages().size(), 0); + QCOMPARE(dst->globalSymbolCount(), 4U); + + Snapshot snapshot; + snapshot.insert(src); + snapshot.insert(dst); + + Class *foo = src->globalSymbolAt(0)->asClass(); + QVERIFY(foo); + QCOMPARE(foo->line(), 1U); + QCOMPARE(foo->column(), 7U); + QCOMPARE(foo->memberCount(), 3U); + Declaration *decl = foo->memberAt(1)->asDeclaration(); + QVERIFY(decl); + QCOMPARE(decl->line(), 4U); + QCOMPARE(decl->column(), 6U); + + CppRefactoringChanges changes(snapshot); + InsertionPointLocator find(changes); + QList locList = find.methodDefinition(decl); + QVERIFY(locList.size() == 1); + InsertionLocation loc = locList.first(); + QCOMPARE(loc.fileName(), dst->fileName()); + QCOMPARE(loc.line(), 7U); + QCOMPARE(loc.column(), 2U); + QCOMPARE(loc.prefix(), QLatin1String("\n\n")); + QCOMPARE(loc.suffix(), QString()); +} diff --git a/src/plugins/cpptools/cpptools.pro b/src/plugins/cpptools/cpptools.pro index f03dac7d32..42fe7721dc 100644 --- a/src/plugins/cpptools/cpptools.pro +++ b/src/plugins/cpptools/cpptools.pro @@ -67,3 +67,8 @@ SOURCES += completionsettingspage.cpp \ FORMS += completionsettingspage.ui \ cppfilesettingspage.ui \ cppcodestylesettingspage.ui + +equals(TEST, 1) { + SOURCES += \ + cppcodegen_test.cpp +} diff --git a/src/plugins/cpptools/cpptoolsplugin.h b/src/plugins/cpptools/cpptoolsplugin.h index 9a88e3bb8d..cd0ef75b59 100644 --- a/src/plugins/cpptools/cpptoolsplugin.h +++ b/src/plugins/cpptools/cpptoolsplugin.h @@ -76,6 +76,21 @@ public: private slots: void switchHeaderSource(); +#ifdef WITH_TESTS + // codegen tests + void test_codegen_public_in_empty_class(); + void test_codegen_public_in_nonempty_class(); + void test_codegen_public_before_protected(); + void test_codegen_private_after_protected(); + void test_codegen_protected_in_nonempty_class(); + void test_codegen_protected_between_public_and_private(); + void test_codegen_qtdesigner_integration(); + void test_codegen_definition_empty_class(); + void test_codegen_definition_first_member(); + void test_codegen_definition_last_member(); + void test_codegen_definition_middle_member(); +#endif + private: QString correspondingHeaderOrSourceI(const QString &fileName) const; diff --git a/tests/auto/cplusplus/codegen/codegen.pro b/tests/auto/cplusplus/codegen/codegen.pro deleted file mode 100644 index 6a56ec42d5..0000000000 --- a/tests/auto/cplusplus/codegen/codegen.pro +++ /dev/null @@ -1,5 +0,0 @@ -include(../../qttest.pri) -include(../shared/shared.pri) -INCLUDEPATH += $$IDE_SOURCE_TREE/src/plugins -SOURCES += tst_codegen.cpp - diff --git a/tests/auto/cplusplus/codegen/tst_codegen.cpp b/tests/auto/cplusplus/codegen/tst_codegen.cpp deleted file mode 100644 index e1425f7cbe..0000000000 --- a/tests/auto/cplusplus/codegen/tst_codegen.cpp +++ /dev/null @@ -1,681 +0,0 @@ -/************************************************************************** -** -** This file is part of Qt Creator -** -** Copyright (c) 2011 Nokia Corporation and/or its subsidiary(-ies). -** -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** -** GNU Lesser General Public License Usage -** -** This file may be used under the terms of the GNU Lesser General Public -** License version 2.1 as published by the Free Software Foundation and -** appearing in the file LICENSE.LGPL included in the packaging of this file. -** Please review the following information to ensure the GNU Lesser General -** Public License version 2.1 requirements will be met: -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** Other Usage -** -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** If you have questions regarding the use of this file, please contact -** Nokia at qt-info@nokia.com. -** -**************************************************************************/ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -//TESTED_COMPONENT=src/libs/cplusplus - -/*! - Tests for various parts of the code generation. Well, okay, currently it only - tests the InsertionPointLocator. - */ -using namespace CPlusPlus; -using namespace CppTools; - -class tst_Codegen: public QObject -{ - Q_OBJECT - -private slots: - void initTestCase(); - void cleanupTestCase(); - void public_in_empty_class(); - void public_in_nonempty_class(); - void public_before_protected(); - void private_after_protected(); - void protected_in_nonempty_class(); - void protected_betwee_public_and_private(); - void qtdesigner_integration(); - void definition_empty_class(); - void definition_first_member(); - void definition_last_member(); - void definition_middle_member(); - -private: - ExtensionSystem::PluginManager *pluginManager; - QString tempPath; -}; - -void tst_Codegen::initTestCase() -{ - pluginManager = new ExtensionSystem::PluginManager; - QSettings *settings = new QSettings(QSettings::IniFormat, QSettings::UserScope, - QLatin1String("Nokia"), QLatin1String("QtCreator")); - pluginManager->setSettings(settings); - pluginManager->setFileExtension(QLatin1String("pluginspec")); - pluginManager->setPluginPaths(QStringList() << QLatin1String(Q_PLUGIN_PATH)); - pluginManager->loadPlugins(); - - tempPath = QDir::tempPath(); -} - -void tst_Codegen::cleanupTestCase() -{ - // gives me a qFatal... -// pluginManager->shutdown(); -// delete pluginManager; -} -/*! - Should insert at line 3, column 1, with "public:\n" as prefix and without suffix. - */ -void tst_Codegen::public_in_empty_class() -{ - const QByteArray src = "\n" - "class Foo\n" // line 1 - "{\n" - "};\n" - "\n"; - - Document::Ptr doc = Document::create("public_in_empty_class"); - doc->setSource(src); - doc->parse(); - doc->check(); - - QCOMPARE(doc->diagnosticMessages().size(), 0); - QCOMPARE(doc->globalSymbolCount(), 1U); - - Class *foo = doc->globalSymbolAt(0)->asClass(); - QVERIFY(foo); - QCOMPARE(foo->line(), 1U); - QCOMPARE(foo->column(), 7U); - - Snapshot snapshot; - snapshot.insert(doc); - CppRefactoringChanges changes(snapshot); - InsertionPointLocator find(changes); - InsertionLocation loc = find.methodDeclarationInClass( - doc->fileName(), - foo, - InsertionPointLocator::Public); - QVERIFY(loc.isValid()); - QCOMPARE(loc.prefix(), QLatin1String("public:\n")); - QVERIFY(loc.suffix().isEmpty()); - QCOMPARE(loc.line(), 3U); - QCOMPARE(loc.column(), 1U); -} - -/*! - Should insert at line 3, column 1, without prefix and without suffix. - */ -void tst_Codegen::public_in_nonempty_class() -{ - const QByteArray src = "\n" - "class Foo\n" // line 1 - "{\n" - "public:\n" // line 3 - "};\n" // line 4 - "\n"; - - Document::Ptr doc = Document::create("public_in_nonempty_class"); - doc->setSource(src); - doc->parse(); - doc->check(); - - QCOMPARE(doc->diagnosticMessages().size(), 0); - QCOMPARE(doc->globalSymbolCount(), 1U); - - Class *foo = doc->globalSymbolAt(0)->asClass(); - QVERIFY(foo); - QCOMPARE(foo->line(), 1U); - QCOMPARE(foo->column(), 7U); - - Snapshot snapshot; - snapshot.insert(doc); - CppRefactoringChanges changes(snapshot); - InsertionPointLocator find(changes); - InsertionLocation loc = find.methodDeclarationInClass( - doc->fileName(), - foo, - InsertionPointLocator::Public); - QVERIFY(loc.isValid()); - QVERIFY(loc.prefix().isEmpty()); - QVERIFY(loc.suffix().isEmpty()); - QCOMPARE(loc.line(), 4U); - QCOMPARE(loc.column(), 1U); -} - -/*! - Should insert at line 3, column 1, with "public:\n" as prefix and "\n suffix. - */ -void tst_Codegen::public_before_protected() -{ - const QByteArray src = "\n" - "class Foo\n" // line 1 - "{\n" - "protected:\n" // line 3 - "};\n" - "\n"; - - Document::Ptr doc = Document::create("public_before_protected"); - doc->setSource(src); - doc->parse(); - doc->check(); - - QCOMPARE(doc->diagnosticMessages().size(), 0); - QCOMPARE(doc->globalSymbolCount(), 1U); - - Class *foo = doc->globalSymbolAt(0)->asClass(); - QVERIFY(foo); - QCOMPARE(foo->line(), 1U); - QCOMPARE(foo->column(), 7U); - - Snapshot snapshot; - snapshot.insert(doc); - CppRefactoringChanges changes(snapshot); - InsertionPointLocator find(changes); - InsertionLocation loc = find.methodDeclarationInClass( - doc->fileName(), - foo, - InsertionPointLocator::Public); - QVERIFY(loc.isValid()); - QCOMPARE(loc.prefix(), QLatin1String("public:\n")); - QCOMPARE(loc.suffix(), QLatin1String("\n")); - QCOMPARE(loc.column(), 1U); - QCOMPARE(loc.line(), 3U); -} - -/*! - Should insert at line 4, column 1, with "private:\n" as prefix and without - suffix. - */ -void tst_Codegen::private_after_protected() -{ - const QByteArray src = "\n" - "class Foo\n" // line 1 - "{\n" - "protected:\n" // line 3 - "};\n" - "\n"; - - Document::Ptr doc = Document::create("private_after_protected"); - doc->setSource(src); - doc->parse(); - doc->check(); - - QCOMPARE(doc->diagnosticMessages().size(), 0); - QCOMPARE(doc->globalSymbolCount(), 1U); - - Class *foo = doc->globalSymbolAt(0)->asClass(); - QVERIFY(foo); - QCOMPARE(foo->line(), 1U); - QCOMPARE(foo->column(), 7U); - - Snapshot snapshot; - snapshot.insert(doc); - CppRefactoringChanges changes(snapshot); - InsertionPointLocator find(changes); - InsertionLocation loc = find.methodDeclarationInClass( - doc->fileName(), - foo, - InsertionPointLocator::Private); - QVERIFY(loc.isValid()); - QCOMPARE(loc.prefix(), QLatin1String("private:\n")); - QVERIFY(loc.suffix().isEmpty()); - QCOMPARE(loc.column(), 1U); - QCOMPARE(loc.line(), 4U); -} - -/*! - Should insert at line 4, column 1, with "protected:\n" as prefix and without - suffix. - */ -void tst_Codegen::protected_in_nonempty_class() -{ - const QByteArray src = "\n" - "class Foo\n" // line 1 - "{\n" - "public:\n" // line 3 - "};\n" // line 4 - "\n"; - - Document::Ptr doc = Document::create("protected_in_nonempty_class"); - doc->setSource(src); - doc->parse(); - doc->check(); - - QCOMPARE(doc->diagnosticMessages().size(), 0); - QCOMPARE(doc->globalSymbolCount(), 1U); - - Class *foo = doc->globalSymbolAt(0)->asClass(); - QVERIFY(foo); - QCOMPARE(foo->line(), 1U); - QCOMPARE(foo->column(), 7U); - - Snapshot snapshot; - snapshot.insert(doc); - CppRefactoringChanges changes(snapshot); - InsertionPointLocator find(changes); - InsertionLocation loc = find.methodDeclarationInClass( - doc->fileName(), - foo, - InsertionPointLocator::Protected); - QVERIFY(loc.isValid()); - QCOMPARE(loc.prefix(), QLatin1String("protected:\n")); - QVERIFY(loc.suffix().isEmpty()); - QCOMPARE(loc.column(), 1U); - QCOMPARE(loc.line(), 4U); -} - -/*! - Should insert at line 4, column 1, with "protected\n" as prefix and "\n" suffix. - */ -void tst_Codegen::protected_betwee_public_and_private() -{ - const QByteArray src = "\n" - "class Foo\n" // line 1 - "{\n" - "public:\n" // line 3 - "private:\n" // line 4 - "};\n" // line 5 - "\n"; - - Document::Ptr doc = Document::create("protected_betwee_public_and_private"); - doc->setSource(src); - doc->parse(); - doc->check(); - - QCOMPARE(doc->diagnosticMessages().size(), 0); - QCOMPARE(doc->globalSymbolCount(), 1U); - - Class *foo = doc->globalSymbolAt(0)->asClass(); - QVERIFY(foo); - QCOMPARE(foo->line(), 1U); - QCOMPARE(foo->column(), 7U); - - Snapshot snapshot; - snapshot.insert(doc); - CppRefactoringChanges changes(snapshot); - InsertionPointLocator find(changes); - InsertionLocation loc = find.methodDeclarationInClass( - doc->fileName(), - foo, - InsertionPointLocator::Protected); - QVERIFY(loc.isValid()); - QCOMPARE(loc.prefix(), QLatin1String("protected:\n")); - QCOMPARE(loc.suffix(), QLatin1String("\n")); - QCOMPARE(loc.column(), 1U); - QCOMPARE(loc.line(), 4U); -} - -/*! - Should insert at line 18, column 1, with "private slots:\n" as prefix and "\n" - as suffix. - - This is the typical Qt Designer case, with test-input like what the integration - generates. - */ -void tst_Codegen::qtdesigner_integration() -{ - const QByteArray src = "/**** Some long (C)opyright notice ****/\n" - "#ifndef MAINWINDOW_H\n" - "#define MAINWINDOW_H\n" - "\n" - "#include \n" - "\n" - "namespace Ui {\n" - " class MainWindow;\n" - "}\n" - "\n" - "class MainWindow : public QMainWindow\n" // line 10 - "{\n" - " Q_OBJECT\n" - "\n" - "public:\n" // line 14 - " explicit MainWindow(QWidget *parent = 0);\n" - " ~MainWindow();\n" - "\n" - "private:\n" // line 18 - " Ui::MainWindow *ui;\n" - "};\n" - "\n" - "#endif // MAINWINDOW_H\n"; - - Document::Ptr doc = Document::create("qtdesigner_integration"); - doc->setSource(src); - doc->parse(); - doc->check(); - - QCOMPARE(doc->diagnosticMessages().size(), 0); - QCOMPARE(doc->globalSymbolCount(), 2U); - - Class *foo = doc->globalSymbolAt(1)->asClass(); - QVERIFY(foo); - QCOMPARE(foo->line(), 10U); - QCOMPARE(foo->column(), 7U); - - Snapshot snapshot; - snapshot.insert(doc); - CppRefactoringChanges changes(snapshot); - InsertionPointLocator find(changes); - InsertionLocation loc = find.methodDeclarationInClass( - doc->fileName(), - foo, - InsertionPointLocator::PrivateSlot); - QVERIFY(loc.isValid()); - QCOMPARE(loc.prefix(), QLatin1String("private slots:\n")); - QCOMPARE(loc.suffix(), QLatin1String("\n")); - QCOMPARE(loc.line(), 18U); - QCOMPARE(loc.column(), 1U); -} - -void tst_Codegen::definition_empty_class() -{ - const QByteArray srcText = "\n" - "class Foo\n" // line 1 - "{\n" - "void foo();\n" // line 3 - "};\n" - "\n"; - - const QByteArray dstText = "\n" - "int x;\n" // line 1 - "\n"; - - Document::Ptr src = Document::create(tempPath + QLatin1String("/file.h")); - Utils::FileSaver srcSaver(src->fileName()); - srcSaver.write(srcText); - srcSaver.finalize(); - src->setSource(srcText); - src->parse(); - src->check(); - QCOMPARE(src->diagnosticMessages().size(), 0); - QCOMPARE(src->globalSymbolCount(), 1U); - - Document::Ptr dst = Document::create(tempPath + QLatin1String("/file.cpp")); - Utils::FileSaver dstSaver(dst->fileName()); - dstSaver.write(dstText); - dstSaver.finalize(); - dst->setSource(dstText); - dst->parse(); - dst->check(); - QCOMPARE(dst->diagnosticMessages().size(), 0); - QCOMPARE(dst->globalSymbolCount(), 1U); - - Snapshot snapshot; - snapshot.insert(src); - snapshot.insert(dst); - - Class *foo = src->globalSymbolAt(0)->asClass(); - QVERIFY(foo); - QCOMPARE(foo->line(), 1U); - QCOMPARE(foo->column(), 7U); - QCOMPARE(foo->memberCount(), 1U); - Declaration *decl = foo->memberAt(0)->asDeclaration(); - QVERIFY(decl); - QCOMPARE(decl->line(), 3U); - QCOMPARE(decl->column(), 6U); - - CppRefactoringChanges changes(snapshot); - InsertionPointLocator find(changes); - QList locList = find.methodDefinition(decl); - QVERIFY(locList.size() == 1); - InsertionLocation loc = locList.first(); - QCOMPARE(loc.fileName(), dst->fileName()); - QCOMPARE(loc.prefix(), QLatin1String("\n\n")); - QCOMPARE(loc.suffix(), QString()); - QCOMPARE(loc.line(), 1U); - QCOMPARE(loc.column(), 7U); -} - -void tst_Codegen::definition_first_member() -{ - const QByteArray srcText = "\n" - "class Foo\n" // line 1 - "{\n" - "void foo();\n" // line 3 - "void bar();\n" // line 4 - "};\n" - "\n"; - - const QByteArray dstText = QString( - "\n" - "#include \"%1/file.h\"\n" // line 1 - "int x;\n" - "\n" - "void Foo::bar()\n" // line 4 - "{\n" - "\n" - "}\n" - "\n" - "int y;\n").arg(tempPath).toLatin1(); - - Document::Ptr src = Document::create(tempPath + QLatin1String("/file.h")); - Utils::FileSaver srcSaver(src->fileName()); - srcSaver.write(srcText); - srcSaver.finalize(); - src->setSource(srcText); - src->parse(); - src->check(); - QCOMPARE(src->diagnosticMessages().size(), 0); - QCOMPARE(src->globalSymbolCount(), 1U); - - Document::Ptr dst = Document::create(tempPath + QLatin1String("/file.cpp")); - dst->addIncludeFile(src->fileName(), 1); - Utils::FileSaver dstSaver(dst->fileName()); - dstSaver.write(dstText); - dstSaver.finalize(); - dst->setSource(dstText); - dst->parse(); - dst->check(); - QCOMPARE(dst->diagnosticMessages().size(), 0); - QCOMPARE(dst->globalSymbolCount(), 3U); - - Snapshot snapshot; - snapshot.insert(src); - snapshot.insert(dst); - - Class *foo = src->globalSymbolAt(0)->asClass(); - QVERIFY(foo); - QCOMPARE(foo->line(), 1U); - QCOMPARE(foo->column(), 7U); - QCOMPARE(foo->memberCount(), 2U); - Declaration *decl = foo->memberAt(0)->asDeclaration(); - QVERIFY(decl); - QCOMPARE(decl->line(), 3U); - QCOMPARE(decl->column(), 6U); - - CppRefactoringChanges changes(snapshot); - InsertionPointLocator find(changes); - QList locList = find.methodDefinition(decl); - QVERIFY(locList.size() == 1); - InsertionLocation loc = locList.first(); - QCOMPARE(loc.fileName(), dst->fileName()); - QCOMPARE(loc.line(), 4U); - QCOMPARE(loc.column(), 1U); - QCOMPARE(loc.suffix(), QLatin1String("\n\n")); - QCOMPARE(loc.prefix(), QString()); -} - -void tst_Codegen::definition_last_member() -{ - const QByteArray srcText = "\n" - "class Foo\n" // line 1 - "{\n" - "void foo();\n" // line 3 - "void bar();\n" // line 4 - "};\n" - "\n"; - - const QByteArray dstText = QString( - "\n" - "#include \"%1/file.h\"\n" // line 1 - "int x;\n" - "\n" - "void Foo::foo()\n" // line 4 - "{\n" - "\n" - "}\n" // line 7 - "\n" - "int y;\n").arg(tempPath).toLatin1(); - - Document::Ptr src = Document::create(tempPath + QLatin1String("/file.h")); - Utils::FileSaver srcSaver(src->fileName()); - srcSaver.write(srcText); - srcSaver.finalize(); - src->setSource(srcText); - src->parse(); - src->check(); - QCOMPARE(src->diagnosticMessages().size(), 0); - QCOMPARE(src->globalSymbolCount(), 1U); - - Document::Ptr dst = Document::create(tempPath + QLatin1String("/file.cpp")); - dst->addIncludeFile(src->fileName(), 1); - Utils::FileSaver dstSaver(dst->fileName()); - dstSaver.write(dstText); - dstSaver.finalize(); - dst->setSource(dstText); - dst->parse(); - dst->check(); - QCOMPARE(dst->diagnosticMessages().size(), 0); - QCOMPARE(dst->globalSymbolCount(), 3U); - - Snapshot snapshot; - snapshot.insert(src); - snapshot.insert(dst); - - Class *foo = src->globalSymbolAt(0)->asClass(); - QVERIFY(foo); - QCOMPARE(foo->line(), 1U); - QCOMPARE(foo->column(), 7U); - QCOMPARE(foo->memberCount(), 2U); - Declaration *decl = foo->memberAt(1)->asDeclaration(); - QVERIFY(decl); - QCOMPARE(decl->line(), 4U); - QCOMPARE(decl->column(), 6U); - - CppRefactoringChanges changes(snapshot); - InsertionPointLocator find(changes); - QList locList = find.methodDefinition(decl); - QVERIFY(locList.size() == 1); - InsertionLocation loc = locList.first(); - QCOMPARE(loc.fileName(), dst->fileName()); - QCOMPARE(loc.line(), 7U); - QCOMPARE(loc.column(), 2U); - QCOMPARE(loc.prefix(), QLatin1String("\n\n")); - QCOMPARE(loc.suffix(), QString()); -} - -void tst_Codegen::definition_middle_member() -{ - const QByteArray srcText = "\n" - "class Foo\n" // line 1 - "{\n" - "void foo();\n" // line 3 - "void bar();\n" // line 4 - "void car();\n" // line 5 - "};\n" - "\n"; - - const QByteArray dstText = QString( - "\n" - "#include \"%1/file.h\"\n" // line 1 - "int x;\n" - "\n" - "void Foo::foo()\n" // line 4 - "{\n" - "\n" - "}\n" // line 7 - "\n" - "void Foo::car()\n" // line 9 - "{\n" - "\n" - "}\n" - "\n" - "int y;\n").arg(tempPath).toLatin1(); - - Document::Ptr src = Document::create(tempPath + QLatin1String("/file.h")); - Utils::FileSaver srcSaver(src->fileName()); - srcSaver.write(srcText); - srcSaver.finalize(); - src->setSource(srcText); - src->parse(); - src->check(); - QCOMPARE(src->diagnosticMessages().size(), 0); - QCOMPARE(src->globalSymbolCount(), 1U); - - Document::Ptr dst = Document::create(tempPath + QLatin1String("/file.cpp")); - dst->addIncludeFile(src->fileName(), 1); - Utils::FileSaver dstSaver(dst->fileName()); - dstSaver.write(dstText); - dstSaver.finalize(); - dst->setSource(dstText); - dst->parse(); - dst->check(); - QCOMPARE(dst->diagnosticMessages().size(), 0); - QCOMPARE(dst->globalSymbolCount(), 4U); - - Snapshot snapshot; - snapshot.insert(src); - snapshot.insert(dst); - - Class *foo = src->globalSymbolAt(0)->asClass(); - QVERIFY(foo); - QCOMPARE(foo->line(), 1U); - QCOMPARE(foo->column(), 7U); - QCOMPARE(foo->memberCount(), 3U); - Declaration *decl = foo->memberAt(1)->asDeclaration(); - QVERIFY(decl); - QCOMPARE(decl->line(), 4U); - QCOMPARE(decl->column(), 6U); - - CppRefactoringChanges changes(snapshot); - InsertionPointLocator find(changes); - QList locList = find.methodDefinition(decl); - QVERIFY(locList.size() == 1); - InsertionLocation loc = locList.first(); - QCOMPARE(loc.fileName(), dst->fileName()); - QCOMPARE(loc.line(), 7U); - QCOMPARE(loc.column(), 2U); - QCOMPARE(loc.prefix(), QLatin1String("\n\n")); - QCOMPARE(loc.suffix(), QString()); -} - -QTEST_MAIN(tst_Codegen) -#include "tst_codegen.moc" diff --git a/tests/auto/cplusplus/cplusplus.pro b/tests/auto/cplusplus/cplusplus.pro index 28ab7b2048..6e94ed407b 100644 --- a/tests/auto/cplusplus/cplusplus.pro +++ b/tests/auto/cplusplus/cplusplus.pro @@ -4,7 +4,6 @@ CONFIG += ordered SUBDIRS = \ ast \ codeformatter \ - codegen \ findusages \ lookup \ preprocessor \ -- cgit v1.2.1