Commit 992f9ed2 authored by Christian Stenger's avatar Christian Stenger
Browse files

AutoTest: Use mark and sweep for parsing



This also removes caching from parser and the respective test info
files are gone now as well.

Change-Id: Ibcea68e446dea532d6addd2f16863738e497bca4
Reviewed-by: default avatarDavid Schulz <david.schulz@theqtcompany.com>
parent fd4d1c80
...@@ -11,7 +11,6 @@ SOURCES += \ ...@@ -11,7 +11,6 @@ SOURCES += \
testtreemodel.cpp \ testtreemodel.cpp \
testtreeitem.cpp \ testtreeitem.cpp \
testvisitor.cpp \ testvisitor.cpp \
testinfo.cpp \
testcodeparser.cpp \ testcodeparser.cpp \
autotestplugin.cpp \ autotestplugin.cpp \
testrunner.cpp \ testrunner.cpp \
...@@ -31,7 +30,6 @@ HEADERS += \ ...@@ -31,7 +30,6 @@ HEADERS += \
testtreemodel.h \ testtreemodel.h \
testtreeitem.h \ testtreeitem.h \
testvisitor.h \ testvisitor.h \
testinfo.h \
testcodeparser.h \ testcodeparser.h \
autotestplugin.h \ autotestplugin.h \
autotest_global.h \ autotest_global.h \
......
...@@ -40,8 +40,6 @@ QtcPlugin { ...@@ -40,8 +40,6 @@ QtcPlugin {
"testcodeparser.h", "testcodeparser.h",
"testconfiguration.cpp", "testconfiguration.cpp",
"testconfiguration.h", "testconfiguration.h",
"testinfo.cpp",
"testinfo.h",
"testnavigationwidget.cpp", "testnavigationwidget.cpp",
"testnavigationwidget.h", "testnavigationwidget.h",
"testresult.cpp", "testresult.cpp",
......
...@@ -105,11 +105,6 @@ void AutoTestUnitTests::testCodeParser() ...@@ -105,11 +105,6 @@ void AutoTestUnitTests::testCodeParser()
QCOMPARE(m_model->namedQuickTestsCount(), expectedNamedQuickTestsCount); QCOMPARE(m_model->namedQuickTestsCount(), expectedNamedQuickTestsCount);
QCOMPARE(m_model->unnamedQuickTestsCount(), expectedUnnamedQuickTestsCount); QCOMPARE(m_model->unnamedQuickTestsCount(), expectedUnnamedQuickTestsCount);
QCOMPARE(m_model->dataTagsCount(), expectedDataTagsCount); QCOMPARE(m_model->dataTagsCount(), expectedDataTagsCount);
QCOMPARE(m_model->parser()->autoTestsCount(), expectedAutoTestsCount);
QCOMPARE(m_model->parser()->namedQuickTestsCount(), expectedNamedQuickTestsCount);
QCOMPARE(m_model->parser()->unnamedQuickTestsCount(), expectedUnnamedQuickTestsCount);
} }
void AutoTestUnitTests::testCodeParser_data() void AutoTestUnitTests::testCodeParser_data()
...@@ -162,12 +157,6 @@ void AutoTestUnitTests::testCodeParserSwitchStartup() ...@@ -162,12 +157,6 @@ void AutoTestUnitTests::testCodeParserSwitchStartup()
m_isQt4 ? 0 : expectedUnnamedQuickTestsCount.at(i)); m_isQt4 ? 0 : expectedUnnamedQuickTestsCount.at(i));
QCOMPARE(m_model->dataTagsCount(), QCOMPARE(m_model->dataTagsCount(),
expectedDataTagsCount.at(i)); expectedDataTagsCount.at(i));
QCOMPARE(m_model->parser()->autoTestsCount(), expectedAutoTestsCount.at(i));
QCOMPARE(m_model->parser()->namedQuickTestsCount(),
m_isQt4 ? 0 : expectedNamedQuickTestsCount.at(i));
QCOMPARE(m_model->parser()->unnamedQuickTestsCount(),
m_isQt4 ? 0 : expectedUnnamedQuickTestsCount.at(i));
} }
} }
...@@ -212,8 +201,6 @@ void AutoTestUnitTests::testCodeParserGTest() ...@@ -212,8 +201,6 @@ void AutoTestUnitTests::testCodeParserGTest()
QVERIFY(parserSpy.wait(20000)); QVERIFY(parserSpy.wait(20000));
QCOMPARE(m_model->gtestNamesCount(), 6); QCOMPARE(m_model->gtestNamesCount(), 6);
// 11 == 3 + 2 + 2 + 2 + 1 + 1, see below
QCOMPARE(m_model->parser()->gtestNamesAndSetsCount(), 11);
QMultiMap<QString, int> expectedNamesAndSets; QMultiMap<QString, int> expectedNamesAndSets;
expectedNamesAndSets.insert(QStringLiteral("FactorialTest"), 3); expectedNamesAndSets.insert(QStringLiteral("FactorialTest"), 3);
...@@ -233,10 +220,6 @@ void AutoTestUnitTests::testCodeParserGTest() ...@@ -233,10 +220,6 @@ void AutoTestUnitTests::testCodeParserGTest()
QCOMPARE(m_model->namedQuickTestsCount(), 0); QCOMPARE(m_model->namedQuickTestsCount(), 0);
QCOMPARE(m_model->unnamedQuickTestsCount(), 0); QCOMPARE(m_model->unnamedQuickTestsCount(), 0);
QCOMPARE(m_model->dataTagsCount(), 0); QCOMPARE(m_model->dataTagsCount(), 0);
QCOMPARE(m_model->parser()->autoTestsCount(), 0);
QCOMPARE(m_model->parser()->namedQuickTestsCount(), 0);
QCOMPARE(m_model->parser()->unnamedQuickTestsCount(), 0);
} }
} // namespace Internal } // namespace Internal
......
This diff is collapsed.
...@@ -44,8 +44,6 @@ namespace Autotest { ...@@ -44,8 +44,6 @@ namespace Autotest {
namespace Internal { namespace Internal {
struct TestCodeLocationAndType; struct TestCodeLocationAndType;
class UnnamedQuickTestInfo;
class GTestInfo;
struct GTestCaseSpec; struct GTestCaseSpec;
class TestCodeParser : public QObject class TestCodeParser : public QObject
...@@ -65,29 +63,9 @@ public: ...@@ -65,29 +63,9 @@ public:
State state() const { return m_parserState; } State state() const { return m_parserState; }
void setDirty() { m_dirty = true; } void setDirty() { m_dirty = true; }
#ifdef WITH_TESTS
int autoTestsCount() const;
int namedQuickTestsCount() const;
int unnamedQuickTestsCount() const;
int gtestNamesAndSetsCount() const;
#endif
// FIXME remove me again
struct ReferencingInfo
{
QString referencingFile;
TestTreeModel::Type type;
};
signals: signals:
void cacheCleared(); void aboutToPerformFullParse();
void testItemCreated(TestTreeItem *item, TestTreeModel::Type type); void testItemCreated(TestTreeItem *item, TestTreeModel::Type type);
void testItemModified(TestTreeItem *tItem, TestTreeModel::Type type, const QStringList &file);
void testItemsRemoved(const QString &filePath, TestTreeModel::Type type);
void unnamedQuickTestsUpdated(const QString &mainFile,
const QMap<QString, TestCodeLocationAndType> &functions);
void unnamedQuickTestsRemoved(const QString &filePath);
void gTestsRemoved(const QString &filePath);
void parsingStarted(); void parsingStarted();
void parsingFinished(); void parsingFinished();
void parsingFailed(); void parsingFailed();
...@@ -105,34 +83,18 @@ public slots: ...@@ -105,34 +83,18 @@ public slots:
void onQmlDocumentUpdated(const QmlJS::Document::Ptr &document); void onQmlDocumentUpdated(const QmlJS::Document::Ptr &document);
void onStartupProjectChanged(ProjectExplorer::Project *); void onStartupProjectChanged(ProjectExplorer::Project *);
void onProjectPartsUpdated(ProjectExplorer::Project *project); void onProjectPartsUpdated(ProjectExplorer::Project *project);
void removeFiles(const QStringList &files);
private: private:
bool postponed(const QStringList &fileList); bool postponed(const QStringList &fileList);
void scanForTests(const QStringList &fileList = QStringList()); void scanForTests(const QStringList &fileList = QStringList());
void clearCache();
void removeTestsIfNecessary(const QString &fileName);
void onTaskStarted(Core::Id type); void onTaskStarted(Core::Id type);
void onAllTasksFinished(Core::Id type); void onAllTasksFinished(Core::Id type);
void onFinished(); void onFinished();
void onPartialParsingFinished(); void onPartialParsingFinished();
void updateUnnamedQuickTests(const QString &fileName, const QString &mainFile,
const QMap<QString, TestCodeLocationAndType> &functions);
void updateModelAndCppDocMap(CPlusPlus::Document::Ptr document,
const QString &declaringFile, TestTreeItem *testItem);
void updateModelAndQuickDocMap(QmlJS::Document::Ptr document,
const QString &referencingFile, TestTreeItem *testItem);
void updateGTests(const CPlusPlus::Document::Ptr &doc,
const QMap<GTestCaseSpec, TestCodeLocationList> &tests);
void removeUnnamedQuickTestsByName(const QString &fileName);
void removeGTestsByName(const QString &fileName);
TestTreeModel *m_model; TestTreeModel *m_model;
QMap<QString, ReferencingInfo> m_referencingFiles;
QList<UnnamedQuickTestInfo> m_unnamedQuickDocList;
QList<GTestInfo> m_gtestDocList;
bool m_codeModelParsing; bool m_codeModelParsing;
bool m_fullUpdatePostponed; bool m_fullUpdatePostponed;
bool m_partialUpdatePostponed; bool m_partialUpdatePostponed;
......
/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of Qt Creator.
**
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3 as published by the Free Software
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
**
****************************************************************************/
#include "testinfo.h"
namespace Autotest {
namespace Internal {
UnnamedQuickTestInfo::UnnamedQuickTestInfo(const QString &function, const QString &fileName)
: m_function(function),
m_fileName(fileName)
{
}
GTestInfo::GTestInfo(const QString &caseName, const QString &setName, const QString &file)
: m_caseName(caseName),
m_setName(setName),
m_fileName(file),
m_enabled(true)
{
}
} // namespace Internal
} // namespace Autotest
/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of Qt Creator.
**
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3 as published by the Free Software
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
**
****************************************************************************/
#ifndef TESTINFO_H
#define TESTINFO_H
#include <QStringList>
namespace Autotest {
namespace Internal {
class UnnamedQuickTestInfo {
public:
explicit UnnamedQuickTestInfo(const QString &function = QString(),
const QString& fileName = QString());
~UnnamedQuickTestInfo() {}
const QString function() const { return m_function; }
void setFunction(const QString &function) { m_function = function; }
const QString fileName() const { return m_fileName; }
void setFileName(const QString &fileName) { m_fileName = fileName; }
private:
QString m_function;
QString m_fileName;
};
class GTestInfo {
public:
explicit GTestInfo(const QString &caseName, const QString &setName, const QString &file);
const QString caseName() const { return m_caseName; }
void setCaseName(const QString &caseName) { m_caseName = caseName; }
const QString setName() const { return m_setName; }
void setSetName(const QString &setName) { m_setName = setName; }
const QString fileName() const { return m_fileName; }
void setFileName(const QString &fileName) { m_fileName = fileName; }
bool isEnabled() const { return m_enabled; }
void setEnabled(bool enabled) { m_enabled = enabled; }
private:
QString m_caseName;
QString m_setName;
QString m_fileName;
bool m_enabled;
};
} // namespace Internal
} // namespace Autotest
#endif // TESTINFO_H
...@@ -86,33 +86,14 @@ TestTreeModel::TestTreeModel(QObject *parent) : ...@@ -86,33 +86,14 @@ TestTreeModel::TestTreeModel(QObject *parent) :
rootItem()->appendChild(m_quickTestRootItem); rootItem()->appendChild(m_quickTestRootItem);
rootItem()->appendChild(m_googleTestRootItem); rootItem()->appendChild(m_googleTestRootItem);
connect(m_parser, &TestCodeParser::cacheCleared, this, connect(m_parser, &TestCodeParser::aboutToPerformFullParse, this,
&TestTreeModel::removeAllTestItems, Qt::QueuedConnection); &TestTreeModel::removeAllTestItems, Qt::QueuedConnection);
connect(m_parser, &TestCodeParser::testItemCreated, connect(m_parser, &TestCodeParser::testItemCreated,
this, &TestTreeModel::addTestTreeItem, Qt::QueuedConnection); this, &TestTreeModel::addTestTreeItem, Qt::QueuedConnection);
connect(m_parser, &TestCodeParser::testItemModified, connect(m_parser, &TestCodeParser::parsingFinished,
this, &TestTreeModel::modifyTestTreeItem, Qt::QueuedConnection); this, &TestTreeModel::sweep, Qt::QueuedConnection);
connect(m_parser, &TestCodeParser::testItemsRemoved, connect(m_parser, &TestCodeParser::parsingFailed,
this, &TestTreeModel::removeTestTreeItems, Qt::QueuedConnection); this, &TestTreeModel::sweep, Qt::QueuedConnection);
connect(m_parser, &TestCodeParser::unnamedQuickTestsUpdated,
this, &TestTreeModel::updateUnnamedQuickTest, Qt::QueuedConnection);
connect(m_parser, &TestCodeParser::unnamedQuickTestsRemoved,
this, &TestTreeModel::removeUnnamedQuickTests, Qt::QueuedConnection);
connect(m_parser, &TestCodeParser::gTestsRemoved,
this, &TestTreeModel::removeGTests, Qt::QueuedConnection);
// CppTools::CppModelManagerInterface *cppMM = CppTools::CppModelManagerInterface::instance();
// if (cppMM) {
// // replace later on by
// // cppMM->registerAstProcessor([this](const CplusPlus::Document::Ptr &doc,
// // const CPlusPlus::Snapshot &snapshot) {
// // checkForQtTestStuff(doc, snapshot);
// // });
// connect(cppMM, SIGNAL(documentUpdated(CPlusPlus::Document::Ptr)),
// this, SLOT(checkForQtTestStuff(CPlusPlus::Document::Ptr)),
// Qt::DirectConnection);
// }
} }
static TestTreeModel *m_instance = 0; static TestTreeModel *m_instance = 0;
...@@ -148,7 +129,7 @@ void TestTreeModel::enableParsing() ...@@ -148,7 +129,7 @@ void TestTreeModel::enableParsing()
connect(cppMM, &CppTools::CppModelManager::documentUpdated, connect(cppMM, &CppTools::CppModelManager::documentUpdated,
m_parser, &TestCodeParser::onCppDocumentUpdated, Qt::QueuedConnection); m_parser, &TestCodeParser::onCppDocumentUpdated, Qt::QueuedConnection);
connect(cppMM, &CppTools::CppModelManager::aboutToRemoveFiles, connect(cppMM, &CppTools::CppModelManager::aboutToRemoveFiles,
m_parser, &TestCodeParser::removeFiles, Qt::QueuedConnection); this, &TestTreeModel::removeFiles, Qt::QueuedConnection);
connect(cppMM, &CppTools::CppModelManager::projectPartsUpdated, connect(cppMM, &CppTools::CppModelManager::projectPartsUpdated,
m_parser, &TestCodeParser::onProjectPartsUpdated); m_parser, &TestCodeParser::onProjectPartsUpdated);
...@@ -156,7 +137,7 @@ void TestTreeModel::enableParsing() ...@@ -156,7 +137,7 @@ void TestTreeModel::enableParsing()
connect(qmlJsMM, &QmlJS::ModelManagerInterface::documentUpdated, connect(qmlJsMM, &QmlJS::ModelManagerInterface::documentUpdated,
m_parser, &TestCodeParser::onQmlDocumentUpdated, Qt::QueuedConnection); m_parser, &TestCodeParser::onQmlDocumentUpdated, Qt::QueuedConnection);
connect(qmlJsMM, &QmlJS::ModelManagerInterface::aboutToRemoveFiles, connect(qmlJsMM, &QmlJS::ModelManagerInterface::aboutToRemoveFiles,
m_parser, &TestCodeParser::removeFiles, Qt::QueuedConnection); this, &TestTreeModel::removeFiles, Qt::QueuedConnection);
m_connectionsInitialized = true; m_connectionsInitialized = true;
} }
...@@ -541,38 +522,6 @@ TestConfiguration *TestTreeModel::getTestConfiguration(const TestTreeItem *item) ...@@ -541,38 +522,6 @@ TestConfiguration *TestTreeModel::getTestConfiguration(const TestTreeItem *item)
return config; return config;
} }
QString TestTreeModel::getMainFileForUnnamedQuickTest(const QString &qmlFile) const
{
const TestTreeItem *unnamed = unnamedQuickTests();
const int count = unnamed ? unnamed->childCount() : 0;
for (int row = 0; row < count; ++row) {
const TestTreeItem *child = unnamed->childItem(row);
if (qmlFile == child->filePath())
return child->mainFile();
}
return QString();
}
void TestTreeModel::qmlFilesForMainFile(const QString &mainFile, QSet<QString> *filePaths) const
{
const TestTreeItem *unnamed = unnamedQuickTests();
if (!unnamed)
return;
for (int row = 0, count = unnamed->childCount(); row < count; ++row) {
const TestTreeItem *child = unnamed->childItem(row);
if (child->mainFile() == mainFile)
filePaths->insert(child->filePath());
}
}
QList<QString> TestTreeModel::getUnnamedQuickTestFunctions() const
{
const TestTreeItem *unnamed = unnamedQuickTests();
if (unnamed)
return unnamed->getChildNames();
return QList<QString>();
}
bool TestTreeModel::hasUnnamedQuickTests() const bool TestTreeModel::hasUnnamedQuickTests() const
{ {
for (int row = 0, count = m_quickTestRootItem->childCount(); row < count; ++row) for (int row = 0, count = m_quickTestRootItem->childCount(); row < count; ++row)
...@@ -591,36 +540,11 @@ TestTreeItem *TestTreeModel::unnamedQuickTests() const ...@@ -591,36 +540,11 @@ TestTreeItem *TestTreeModel::unnamedQuickTests() const
return 0; return 0;
} }
void TestTreeModel::removeUnnamedQuickTests(const QString &filePath) void TestTreeModel::removeFiles(const QStringList &files)
{ {
TestTreeItem *unnamedQT = unnamedQuickTests(); foreach (const QString &file, files)
if (!unnamedQT) markForRemoval(file);
return; sweep();
for (int childRow = unnamedQT->childCount() - 1; childRow >= 0; --childRow) {
TestTreeItem *child = unnamedQT->childItem(childRow);
if (filePath == child->filePath())
delete takeItem(child);
}
if (unnamedQT->childCount() == 0)
delete takeItem(unnamedQT);
emit testTreeModelChanged();
}
void TestTreeModel::removeGTests(const QString &filePath)
{
for (int childRow = m_googleTestRootItem->childCount() - 1; childRow >= 0; --childRow) {
TestTreeItem *child = m_googleTestRootItem->childItem(childRow);
for (int grandChildRow = child->childCount() - 1; grandChildRow >= 0; --grandChildRow) {
TestTreeItem *grandChild = child->childItem(grandChildRow);
if (filePath == grandChild->filePath())
delete takeItem(grandChild);
}
if (child->childCount() == 0)
delete takeItem(child);
}
emit testTreeModelChanged();
} }
void TestTreeModel::markAllForRemoval() void TestTreeModel::markAllForRemoval()
...@@ -711,78 +635,59 @@ QMap<QString, QString> TestTreeModel::referencingFiles() const ...@@ -711,78 +635,59 @@ QMap<QString, QString> TestTreeModel::referencingFiles() const
return finder.referencingFiles(); return finder.referencingFiles();
} }
void TestTreeModel::addTestTreeItem(TestTreeItem *item, TestTreeModel::Type type) TestTreeItem *TestTreeModel::findTestTreeItemByContent(TestTreeItem *item, TestTreeItem *parent,
Type type)
{ {
TestTreeItem *parent = rootItemForType(type); for (int row = 0, count = parent->childCount(); row < count; ++row) {
if (type == TestTreeModel::GoogleTest) { TestTreeItem *current = parent->childItem(row);
// check if there's already an item with the same test name... if (current->name() != item->name())
TestTreeItem *toBeUpdated = 0; continue;
for (int row = 0, count = parent->childCount(); row < count; ++row) {
TestTreeItem *current = parent->childItem(row);
if (current->name() == item->name() && current->type() == item->type()) {
toBeUpdated = current;
break;
}
}
// ...if so we have, to update this one instead of adding a new item
if (toBeUpdated) {
for (int row = 0, count = item->childCount(); row < count; ++row)
toBeUpdated->appendChild(new TestTreeItem(*item->childItem(row)));
delete item;
} else {
parent->appendChild(item);
}
} else {
parent->appendChild(item);
}
emit testTreeModelChanged();
}
void TestTreeModel::updateUnnamedQuickTest(const QString &mainFile,
const QMap<QString, TestCodeLocationAndType> &functions)
{
if (functions.isEmpty())
return;
if (!hasUnnamedQuickTests()) switch (type) {
addTestTreeItem(new TestTreeItem(QString(), QString(), TestTreeItem::TestClass), QuickTest); case AutoTest:
if (current->filePath() == item->filePath())
TestTreeItem *unnamed = unnamedQuickTests(); return current;
foreach (const QString &functionName, functions.keys()) { break;
const TestCodeLocationAndType locationAndType = functions.value(functionName); case QuickTest:
TestTreeItem *testFunction = new TestTreeItem(functionName, locationAndType.m_name, if (current->filePath() == item->filePath() && current->mainFile() == item->mainFile())
locationAndType.m_type); return current;
testFunction->setLine(locationAndType.m_line); break;
testFunction->setColumn(locationAndType.m_column); case GoogleTest:
testFunction->setMainFile(mainFile); if (current->type() == item->type())
unnamed->appendChild(testFunction); return current;
break;
}
} }
return 0;
} }
void TestTreeModel::modifyTestTreeItem(TestTreeItem *item, TestTreeModel::Type type, const QStringList &files) void TestTreeModel::addTestTreeItem(TestTreeItem *item, Type type)
{ {
QModelIndex index = rootIndexForType(type);
TestTreeItem *parent = rootItemForType(type); TestTreeItem *parent = rootItemForType(type);
if (files.isEmpty()) { TestTreeItem *toBeUpdated = findTestTreeItemByContent(item, parent, type);
if (TestTreeItem *unnamed = unnamedQuickTests()) { const int count = item->childCount();
if (unnamed == item) // no need to update or delete if (toBeUpdated) {
return; if (!toBeUpdated->markedForRemoval()) {
for (int row = 0; row < count; ++row)
index = indexForItem(unnamed); toBeUpdated->appendChild(new TestTreeItem(*item->childItem(row)));
modifyTestSubtree(index, item); } else {
} for (int childRow = count - 1; childRow >= 0; --childRow) {
} else { TestTreeItem *childItem = item->childItem(childRow);
for (int row = 0; row < parent->childCount(); ++row) { TestTreeItem *origChild = findTestTreeItemByContent(childItem, toBeUpdated, type);
if (files.contains(parent->childItem(row)->filePath())) { if (origChild) {
index = index.child(row, 0); QModelIndex toBeModifiedIndex = indexForItem(origChild);
modifyTestSubtree(index, item); modifyTestSubtree(toBeModifiedIndex, childItem);
break; } else {
toBeUpdated->insertChild(qMin(count, toBeUpdated->childCount()),
new TestTreeItem(*childItem));