Commit e3c0a1ad authored by Kevin Funk's avatar Kevin Funk
Browse files

Fix memleaks in unittests

Summary:
Fix memory leaks in unittests to make it easier to find real memory leaks in the tested code.

Fixed tests:
- test_projectmodel
- test_areaoperation
- test_controller
- test_toolviewtoolbar
- test_viewactivation

NOTE: this does not fix all memory leaks in all unittests, this is just s start to keep the changes small

Test Plan:
- cmake -DCMAKE_BUILD_TYPE=Debug -DECM_ENABLE_SANITIZERS='address' -DBUILD_TESTING=ON ..
- make test

Many tests will fail because of LSAN (leak sanitizer), which is enabled (at least here) by default with ASAN.

Reviewers: #kdevelop, kfunk

Reviewed By: #kdevelop, kfunk

Subscribers: brauch, kfunk, kdevelop-devel

Tags: #kdevelop

Differential Revision: https://phabricator.kde.org/D16064
parent 2bb9401f
......@@ -307,11 +307,11 @@ void TestProjectModel::testItemSanity()
void TestProjectModel::testTakeRow()
{
ProjectBaseItem* parent = new ProjectBaseItem( nullptr, QStringLiteral("test") );
ProjectBaseItem* child = new ProjectBaseItem( nullptr, QStringLiteral("test"), parent );
ProjectBaseItem* subchild = new ProjectBaseItem( nullptr, QStringLiteral("subtest"), child );
QScopedPointer<ProjectBaseItem> parent(new ProjectBaseItem( nullptr, QStringLiteral("test") ));
QScopedPointer<ProjectBaseItem> child(new ProjectBaseItem( nullptr, QStringLiteral("test"), parent.data() ));
QScopedPointer<ProjectBaseItem> subchild(new ProjectBaseItem( nullptr, QStringLiteral("subtest"), child.data() ));
model->appendRow( parent );
model->appendRow( parent.data() );
QCOMPARE( parent->model(), model );
QCOMPARE( child->model(), model );
......@@ -333,15 +333,15 @@ void TestProjectModel::testRename()
QFETCH( int, expectedRenameCode );
const Path projectFolder = Path(QUrl::fromLocalFile(QStringLiteral("/dummyprojectfolder")));
TestProject* proj = new TestProject;
ProjectFolderItem* rootItem = new ProjectFolderItem( proj, projectFolder, nullptr);
QScopedPointer<TestProject> proj(new TestProject());
ProjectFolderItem* rootItem = new ProjectFolderItem( proj.data(), projectFolder, nullptr);
proj->setProjectItem( rootItem );
new ProjectFileItem(QStringLiteral("existing"), rootItem);
ProjectBaseItem* item = nullptr;
if( itemType == ProjectBaseItem::Target ) {
item = new ProjectTargetItem( proj, itemText, rootItem );
item = new ProjectTargetItem( proj.data(), itemText, rootItem );
} else if( itemType == ProjectBaseItem::File ) {
item = new ProjectFileItem( itemText, rootItem );
} else if( itemType == ProjectBaseItem::Folder ) {
......@@ -448,8 +448,8 @@ void TestProjectModel::testRename_data()
void TestProjectModel::testWithProject()
{
TestProject* proj = new TestProject();
ProjectFolderItem* rootItem = new ProjectFolderItem( proj, Path(QUrl::fromLocalFile(QStringLiteral("/dummyprojectfolder"))), nullptr);
QScopedPointer<TestProject> proj(new TestProject());
ProjectFolderItem* rootItem = new ProjectFolderItem( proj.data(), Path(QUrl::fromLocalFile(QStringLiteral("/dummyprojectfolder"))), nullptr);
proj->setProjectItem( rootItem );
ProjectBaseItem* item = model->itemFromIndex( model->index( 0, 0 ) );
QCOMPARE( item, rootItem );
......@@ -519,11 +519,11 @@ void TestProjectModel::testProjectProxyModel()
void TestProjectModel::testProjectFileSet()
{
TestProject* project = new TestProject;
QScopedPointer<TestProject> project(new TestProject());
QVERIFY(project->fileSet().isEmpty());
Path path(QUrl::fromLocalFile(QDir::tempPath() + "/a"));
ProjectFileItem* item = new ProjectFileItem(project, path, project->projectItem());
ProjectFileItem* item = new ProjectFileItem(project.data(), path, project->projectItem());
QCOMPARE(project->fileSet().size(), 1);
qDebug() << path << project->fileSet().toList().at(0).toUrl();
QCOMPARE(Path(project->fileSet().toList().at(0).toUrl()), path);
......@@ -535,7 +535,7 @@ void TestProjectModel::testProjectFileIcon()
{
QMimeDatabase db;
ProjectFileItem* item = new ProjectFileItem(nullptr, Path(QDir::tempPath() + "/foo.txt"));
QScopedPointer<ProjectFileItem> item(new ProjectFileItem(nullptr, Path(QDir::tempPath() + "/foo.txt")));
const QString txtIcon = db.mimeTypeForUrl(item->path().toUrl()).iconName();
QCOMPARE(item->iconName(), txtIcon);
item->setPath(Path(QDir::tempPath() + "/bar.cpp"));
......@@ -543,4 +543,4 @@ void TestProjectModel::testProjectFileIcon()
QVERIFY(item->iconName() != txtIcon);
}
QTEST_MAIN( TestProjectModel)
QTEST_MAIN(TestProjectModel)
......@@ -333,9 +333,7 @@ struct AreaWidgetChecker {
}
return Area::ContinueWalker;
}
char* message() {
return qstrdup(failureMessage.toLatin1().data());
}
bool foundViewWithoutWidget = false;
QString failureMessage;
};
......@@ -353,7 +351,7 @@ void TestAreaOperation::areaSwitchingInSameMainwindow()
AreaWidgetChecker checker;
m_area1->walkViews(checker, m_area1->rootIndex());
m_area1->walkToolViews(checker, Sublime::AllPositions);
QVERIFY2(!checker.foundViewWithoutWidget, checker.message());
QVERIFY2(!checker.foundViewWithoutWidget, checker.failureMessage.toLatin1().data());
}
void TestAreaOperation::simpleViewAdditionAndDeletion()
......
......@@ -40,15 +40,15 @@ void TestController::documentDeletion()
void TestController::areaDeletion()
{
Controller* controller = new Controller;
Document *doc = new ToolDocument(QStringLiteral("tool"), controller, new SimpleToolWidgetFactory<QTextEdit>(QStringLiteral("tool")));
Controller controller;
Document *doc = new ToolDocument(QStringLiteral("tool"), &controller, new SimpleToolWidgetFactory<QTextEdit>(QStringLiteral("tool")));
//create a view which does not belong to an area
View* view1 = doc->createView();
Q_UNUSED(view1);
//create an area and two views in it
Area *area = new Area(controller, QStringLiteral("MyArea"));
controller->addDefaultArea(area);
QCOMPARE(controller->defaultAreas().count(), 1);
Area *area = new Area(&controller, QStringLiteral("MyArea"));
controller.addDefaultArea(area);
QCOMPARE(controller.defaultAreas().count(), 1);
View* view2 = doc->createView();
view2->setObjectName(QStringLiteral("VIEW2"));
area->addView(view2);
......@@ -63,7 +63,7 @@ void TestController::areaDeletion()
QEXPECT_FAIL("", "Fails because of delayed view deletion", Continue);
QCOMPARE(doc->views().count(), 1);
QCOMPARE(controller->defaultAreas().count(), 0);
QCOMPARE(controller.defaultAreas().count(), 0);
QTest::qWait(100); // wait for deleteLaters
qDebug() << "Deleting doc";
......
......@@ -39,10 +39,22 @@ public:
explicit ToolViewToolBarFactory(const QString &id): SimpleToolWidgetFactory<QTextEdit>(id) {}
QList<QAction*> toolBarActions( QWidget* ) const override
{
QAction* action = new QAction(actionText, nullptr);
return QList<QAction*>() << action;
return actionList;
}
QString actionText;
~ToolViewToolBarFactory() override
{
qDeleteAll(actionList);
}
void addAction(const QString &text)
{
QAction* action = new QAction(text, nullptr);
actionList.append(action);
}
private:
QList<QAction*> actionList;
};
void TestToolViewToolBar::init()
......@@ -55,7 +67,7 @@ void TestToolViewToolBar::init()
// a horizontal tool with toolbar
ToolViewToolBarFactory* factoryT1 = new ToolViewToolBarFactory(QStringLiteral("tool1factory"));
actionTextT1 = QStringLiteral("Tool1Action");
factoryT1->actionText = actionTextT1;
factoryT1->addAction(actionTextT1);
tool1 = new ToolDocument( QStringLiteral("tool1"), controller, factoryT1 );
viewT11 = tool1->createView();
area->addToolView( viewT11, Sublime::Bottom );
......@@ -63,7 +75,7 @@ void TestToolViewToolBar::init()
// a vertical tool with toolbar
ToolViewToolBarFactory* factoryT2 = new ToolViewToolBarFactory(QStringLiteral("tool2factory"));
actionTextT2 = QStringLiteral("Tool2Action");
factoryT2->actionText = actionTextT2;
factoryT2->addAction(actionTextT2);
tool2 = new ToolDocument( QStringLiteral("tool2"), controller, factoryT2 );
viewT21 = tool2->createView();
area->addToolView( viewT21, Sublime::Left );
......@@ -90,6 +102,7 @@ QToolBar* TestToolViewToolBar::fetchToolBarFor(Sublime::View* view)
char* failMsg = qstrdup(QStringLiteral("Expected to find a toolbar but found %1").arg(barCount).toLatin1().data());
Q_UNUSED(failMsg);
Q_ASSERT_X(barCount == 1, loc, failMsg);
delete [] failMsg;
return toolBars.at(0);
}
......
......@@ -143,37 +143,38 @@ void TestViewActivation::viewActivation()
dock->setWidget(toolBreaker);
mw->addDockWidget(Qt::LeftDockWidgetArea, dock);
QFocusEvent focusEvent(QEvent::FocusIn);
//now post events to the widgets and see if mainwindow has the right active views
//activate view
qApp->sendEvent(view212->widget(), new QFocusEvent(QEvent::FocusIn));
qApp->sendEvent(view212->widget(), &focusEvent);
QString failMsg = QStringLiteral("\nWas expecting %1 to be active but got %2").
arg(view212->objectName(), mw->activeView()->objectName());
QVERIFY2(mw->activeView() == view212, failMsg.toLatin1().data());
//activate tool view and check that both view and tool view are active
qApp->sendEvent(viewT31->widget(), new QFocusEvent(QEvent::FocusIn));
qApp->sendEvent(viewT31->widget(), &focusEvent);
QCOMPARE(mw->activeView(), view212);
QCOMPARE(mw->activeToolView(), viewT31);
//active another view
qApp->sendEvent(view241->widget(), new QFocusEvent(QEvent::FocusIn));
qApp->sendEvent(view241->widget(), &focusEvent);
QCOMPARE(mw->activeView(), view241);
QCOMPARE(mw->activeToolView(), viewT31);
//focus a widget not in the area
qApp->sendEvent(breaker, new QFocusEvent(QEvent::FocusIn));
qApp->sendEvent(breaker, &focusEvent);
QCOMPARE(mw->activeView(), view241);
QCOMPARE(mw->activeToolView(), viewT31);
//focus a dock not in the area
qApp->sendEvent(toolBreaker, new QFocusEvent(QEvent::FocusIn));
qApp->sendEvent(toolBreaker, &focusEvent);
QCOMPARE(mw->activeView(), view241);
QCOMPARE(mw->activeToolView(), viewT31);
//focus inner widget for view221
QListView *inner = mw->findChild<QListView*>(QStringLiteral("doc2_inner"));
QVERIFY(inner);
qApp->sendEvent(inner, new QFocusEvent(QEvent::FocusIn));
qApp->sendEvent(inner, &focusEvent);
QCOMPARE(mw->activeView(), view221);
QCOMPARE(mw->activeToolView(), viewT31);
}
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment