Make VCS data container classes implicitly shared

Summary:
Also
* rely on default implementation of copy constructor to copy all data
  on forking the internal data objects
* mark as movable types for improved handling in Qt containers

Object of these classes are created in one place and then passed around
for read-only consumption. They are passed by value in method return
arguments and stored by value. As the classes already have a private
object for pimpl, making this an implicitly shared one is a small step.

Reviewers: #kdevelop, apol, mwolff

Reviewed By: #kdevelop, apol, mwolff

Subscribers: apol, mwolff, brauch, kdevelop-devel

Differential Revision: https://phabricator.kde.org/D8588
parent a6d34506
add_definitions(-DTRANSLATION_DOMAIN=\"kdevplatform\")
if(BUILD_TESTING)
add_subdirectory(tests)
add_subdirectory(dvcs/tests)
add_subdirectory(models/tests)
endif()
......
ecm_add_test(test_vcsrevision
LINK_LIBRARIES Qt5::Test KDev::Vcs
)
ecm_add_test(test_vcsannotationline
LINK_LIBRARIES Qt5::Test KDev::Vcs
)
ecm_add_test(test_vcsannotation
LINK_LIBRARIES Qt5::Test KDev::Vcs
)
ecm_add_test(test_vcsitemevent
LINK_LIBRARIES Qt5::Test KDev::Vcs
)
ecm_add_test(test_vcsevent
LINK_LIBRARIES Qt5::Test KDev::Vcs
)
ecm_add_test(test_vcsstatusinfo
LINK_LIBRARIES Qt5::Test KDev::Vcs
)
ecm_add_test(test_vcsdiff
LINK_LIBRARIES Qt5::Test KDev::Vcs
)
/* This file is part of KDevelop
*
* Copyright 2017 Friedrich W. H. Kossebau <kossebau@kde.org>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301, USA.
*/
#include "test_vcsannotation.h"
#include <QTest>
#include <vcs/vcsannotation.h>
#include <vcs/vcsrevision.h>
using namespace KDevelop;
static
VcsAnnotationLine createAnnotationLine(int lineNumber,
const QString& text,
const QString& author,
const VcsRevision& revision,
const QDateTime& date,
const QString& commitMessage)
{
VcsAnnotationLine annotationLine;
annotationLine.setLineNumber(lineNumber);
annotationLine.setText(text);
annotationLine.setAuthor(author);
annotationLine.setRevision(revision);
annotationLine.setDate(date);
annotationLine.setCommitMessage(commitMessage);
return annotationLine;
}
void TestVcsAnnotation::testCopyConstructor()
{
const int lineNumber = 1;
const QString text("Text A");
const QString author("Author A");
VcsRevision revision;
revision.setRevisionValue("A", VcsRevision::GlobalNumber);
const QDateTime date = QDateTime::fromString("2001-01-01T00:00:00+00:00", Qt::ISODate);
const QString commitMessage("Commit A");
const VcsAnnotationLine annotationLine = createAnnotationLine(lineNumber, text, author, revision, date, commitMessage);
const QUrl location(QStringLiteral("git://foo"));
// test plain copy
{
VcsAnnotation annotationA;
annotationA.setLocation(location);
annotationA.insertLine(lineNumber, annotationLine);
VcsAnnotation annotationB(annotationA);
QCOMPARE(annotationA.location(), location);
QCOMPARE(annotationA.lineCount(), 1);
QVERIFY(annotationA.containsLine(lineNumber));
QCOMPARE(annotationB.location(), location);
QCOMPARE(annotationB.lineCount(), 1);
QVERIFY(annotationB.containsLine(lineNumber));
}
const QUrl locationNew(QStringLiteral("svn://bar"));
// test detach after changing A
{
VcsAnnotation annotationA;
annotationA.setLocation(location);
annotationA.insertLine(lineNumber, annotationLine);
VcsAnnotation annotationB(annotationA);
// change a property of A
annotationA.setLocation(locationNew);
QCOMPARE(annotationA.location(), locationNew);
QCOMPARE(annotationA.lineCount(), 1);
QVERIFY(annotationA.containsLine(lineNumber));
QCOMPARE(annotationB.location(), location);
QCOMPARE(annotationB.lineCount(), 1);
QVERIFY(annotationB.containsLine(lineNumber));
}
}
void TestVcsAnnotation::testAssignOperator()
{
const int lineNumber = 1;
const QString text("Text A");
const QString author("Author A");
VcsRevision revision;
revision.setRevisionValue("A", VcsRevision::GlobalNumber);
const QDateTime date = QDateTime::fromString("2001-01-01T00:00:00+00:00", Qt::ISODate);
const QString commitMessage("Commit A");
const VcsAnnotationLine annotationLine = createAnnotationLine(lineNumber, text, author, revision, date, commitMessage);
const QUrl location(QStringLiteral("http://kdevelop.org"));
// test plain copy
{
VcsAnnotation annotationA;
annotationA.setLocation(location);
annotationA.insertLine(lineNumber, annotationLine);
VcsAnnotation annotationB;
annotationB = annotationA;
QCOMPARE(annotationA.location(), location);
QCOMPARE(annotationA.lineCount(), 1);
QVERIFY(annotationA.containsLine(lineNumber));
QCOMPARE(annotationB.location(), location);
QCOMPARE(annotationB.lineCount(), 1);
QVERIFY(annotationB.containsLine(lineNumber));
}
const QUrl locationNew(QStringLiteral("http://kate-editor.org"));
// test detach after changing A
{
VcsAnnotation annotationA;
annotationA.setLocation(location);
annotationA.insertLine(lineNumber, annotationLine);
VcsAnnotation annotationB;
annotationB = annotationA;
// change a property of A
annotationA.setLocation(locationNew);
QCOMPARE(annotationA.location(), locationNew);
QCOMPARE(annotationA.lineCount(), 1);
QVERIFY(annotationA.containsLine(lineNumber));
QCOMPARE(annotationB.location(), location);
QCOMPARE(annotationB.lineCount(), 1);
QVERIFY(annotationB.containsLine(lineNumber));
}
}
QTEST_GUILESS_MAIN(TestVcsAnnotation);
/* This file is part of KDevelop
*
* Copyright 2017 Friedrich W. H. Kossebau <kossebau@kde.org>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301, USA.
*/
#ifndef KDEVPLATFORM_TESTVCSANNOTATION_H
#define KDEVPLATFORM_TESTVCSANNOTATION_H
#include <QObject>
class TestVcsAnnotation : public QObject
{
Q_OBJECT
private Q_SLOTS:
void testCopyConstructor();
void testAssignOperator();
};
#endif // KDEVPLATFORM_TESTVCSANNOTATION_H
/* This file is part of KDevelop
*
* Copyright 2017 Friedrich W. H. Kossebau <kossebau@kde.org>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301, USA.
*/
#include "test_vcsannotationline.h"
#include <QTest>
#include <vcs/vcsannotation.h>
#include <vcs/vcsrevision.h>
using namespace KDevelop;
void TestVcsAnnotationLine::setAnnotationLine(VcsAnnotationLine& annotationLine,
int lineNumber,
const QString& text,
const QString& author,
const VcsRevision& revision,
const QDateTime& date,
const QString& commitMessage)
{
annotationLine.setLineNumber(lineNumber);
annotationLine.setText(text);
annotationLine.setAuthor(author);
annotationLine.setRevision(revision);
annotationLine.setDate(date);
annotationLine.setCommitMessage(commitMessage);
}
void TestVcsAnnotationLine::compareAnnotationLine(const VcsAnnotationLine& annotationLine,
int lineNumber,
const QString& text,
const QString& author,
const VcsRevision& revision,
const QDateTime& date,
const QString& commitMessage)
{
QCOMPARE(annotationLine.lineNumber(), lineNumber);
QCOMPARE(annotationLine.text(), text);
QCOMPARE(annotationLine.author(), author);
QCOMPARE(annotationLine.revision(), revision);
QCOMPARE(annotationLine.date(), date);
QCOMPARE(annotationLine.commitMessage(), commitMessage);
}
void TestVcsAnnotationLine::testCopyConstructor()
{
// copy invalid
{
VcsAnnotationLine annotationLineA;
VcsAnnotationLine annotationLineB(annotationLineA);
QCOMPARE(annotationLineA.revision().revisionType(), VcsRevision::Invalid);
QCOMPARE(annotationLineB.revision().revisionType(), VcsRevision::Invalid);
}
// test plain copy
const int lineNumber = 1;
const QString text("Text A");
const QString author("Author A");
VcsRevision revision;
revision.setRevisionValue("A", VcsRevision::GlobalNumber);
const QDateTime date = QDateTime::fromString("2001-01-01T00:00:00+00:00", Qt::ISODate);
const QString commitMessage("Commit A");
{
VcsAnnotationLine annotationLineA;
setAnnotationLine(annotationLineA,
lineNumber, text, author, revision, date, commitMessage);
VcsAnnotationLine annotationLineB(annotationLineA);
compareAnnotationLine(annotationLineA,
lineNumber, text, author, revision, date, commitMessage);
compareAnnotationLine(annotationLineB,
lineNumber, text, author, revision, date, commitMessage);
}
const int lineNumberNew = 10;
// test detach after changing A
{
VcsAnnotationLine annotationLineA;
setAnnotationLine(annotationLineA,
lineNumber, text, author, revision, date, commitMessage);
VcsAnnotationLine annotationLineB(annotationLineA);
// change a property of A
annotationLineA.setLineNumber(lineNumberNew);
compareAnnotationLine(annotationLineA,
lineNumberNew, text, author, revision, date, commitMessage);
compareAnnotationLine(annotationLineB,
lineNumber, text, author, revision, date, commitMessage);
}
}
void TestVcsAnnotationLine::testAssignOperator()
{
// assign invalid
{
VcsAnnotationLine annotationLineA;
VcsAnnotationLine annotationLineB;
VcsRevision revision;
revision.setRevisionValue(2, VcsRevision::FileNumber);
annotationLineB.setRevision(revision);
annotationLineB = annotationLineA;
QCOMPARE(annotationLineA.revision().revisionType(), VcsRevision::Invalid);
QCOMPARE(annotationLineB.revision().revisionType(), VcsRevision::Invalid);
}
// test plain assign
const int lineNumber = 1;
const QString text("Text A");
const QString author("Author A");
VcsRevision revision;
revision.setRevisionValue("A", VcsRevision::GlobalNumber);
const QDateTime date = QDateTime::fromString("2001-01-01T00:00:00+00:00", Qt::ISODate);
const QString commitMessage("Commit A");
{
VcsAnnotationLine annotationLineA;
setAnnotationLine(annotationLineA,
lineNumber, text, author, revision, date, commitMessage);
VcsAnnotationLine annotationLineB;
annotationLineB = annotationLineA;
compareAnnotationLine(annotationLineA,
lineNumber, text, author, revision, date, commitMessage);
compareAnnotationLine(annotationLineB,
lineNumber, text, author, revision, date, commitMessage);
}
const int lineNumberNew = 10;
// test detach after changing A
{
VcsAnnotationLine annotationLineA;
setAnnotationLine(annotationLineA,
lineNumber, text, author, revision, date, commitMessage);
VcsAnnotationLine annotationLineB;
annotationLineB = annotationLineA;
// change a property of A
annotationLineA.setLineNumber(lineNumberNew);
compareAnnotationLine(annotationLineA,
lineNumberNew, text, author, revision, date, commitMessage);
compareAnnotationLine(annotationLineB,
lineNumber, text, author, revision, date, commitMessage);
}
}
QTEST_GUILESS_MAIN(TestVcsAnnotationLine);
/* This file is part of KDevelop
*
* Copyright 2017 Friedrich W. H. Kossebau <kossebau@kde.org>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301, USA.
*/
#ifndef KDEVPLATFORM_TESTVCSANNOTATIONLINE_H
#define KDEVPLATFORM_TESTVCSANNOTATIONLINE_H
#include <QObject>
namespace KDevelop {
class VcsAnnotationLine;
class VcsRevision;
}
class QDateTime;
class QString;
class TestVcsAnnotationLine : public QObject
{
Q_OBJECT
private Q_SLOTS:
void testCopyConstructor();
void testAssignOperator();
private:
void setAnnotationLine(KDevelop::VcsAnnotationLine& annotationLine,
int lineNumber,
const QString& text,
const QString& author,
const KDevelop::VcsRevision& revision,
const QDateTime& date,
const QString& commitMessage);
void compareAnnotationLine(const KDevelop::VcsAnnotationLine& annotationLine,
int lineNumber,
const QString& text,
const QString& author,
const KDevelop::VcsRevision& revision,
const QDateTime& date,
const QString& commitMessage);
};
#endif // KDEVPLATFORM_TESTVCSANNOTATIONLINE_H
/* This file is part of KDevelop
*
* Copyright 2017 Friedrich W. H. Kossebau <kossebau@kde.org>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301, USA.
*/
#include "test_vcsdiff.h"
#include <QTest>
#include <vcs/vcslocation.h>
using namespace KDevelop;
void TestVcsDiff::setDiff(VcsDiff& diff,
VcsDiff::Type type,
VcsDiff::Content contentType,
const QString& diffString,
const QUrl& baseDiff,
uint depth,
const QHash<VcsLocation,QByteArray>& leftBinaries,
const QHash<VcsLocation,QByteArray>& rightBinaries,
const QHash<VcsLocation,QString>& leftTexts,
const QHash<VcsLocation,QString>& rightTexts)
{
diff.setType(type);
diff.setContentType(contentType);
diff.setDiff(diffString);
diff.setBaseDiff(baseDiff);
diff.setDepth(depth);
for (auto it = leftBinaries.begin(); it != leftBinaries.end(); ++it)
diff.addLeftBinary(it.key(), it.value());
for (auto it = rightBinaries.begin(); it != rightBinaries.end(); ++it)
diff.addRightBinary(it.key(), it.value());
for (auto it = leftTexts.begin(); it != leftTexts.end(); ++it)
diff.addLeftText(it.key(), it.value());
for (auto it = rightTexts.begin(); it != rightTexts.end(); ++it)
diff.addRightText(it.key(), it.value());
}
void TestVcsDiff::compareDiff(const VcsDiff& diff,
VcsDiff::Type type,
VcsDiff::Content contentType,
const QString& diffString,
const QUrl& baseDiff,
uint depth,
const QHash<VcsLocation,QByteArray>& leftBinaries,
const QHash<VcsLocation,QByteArray>& rightBinaries,
const QHash<VcsLocation,QString>& leftTexts,
const QHash<VcsLocation,QString>& rightTexts)
{
QCOMPARE(diff.type(), type);
QCOMPARE(diff.contentType(), contentType);
QCOMPARE(diff.diff(), diffString);
QCOMPARE(diff.baseDiff(), baseDiff);
QCOMPARE(diff.depth(), depth);
QCOMPARE(diff.leftBinaries(), leftBinaries);
QCOMPARE(diff.rightBinaries(), rightBinaries);
QCOMPARE(diff.leftTexts(), leftTexts);
QCOMPARE(diff.rightTexts(), rightTexts);
}
void TestVcsDiff::testCopyConstructor()
{
// test plain copy
const VcsDiff::Type type = VcsDiff::DiffRaw;
const VcsDiff::Content contentType = VcsDiff::Binary;
const QString diffString("diff");
const QUrl baseDiff("git://1");
const uint depth = 1;
const VcsLocation location("server");
const QHash<VcsLocation,QByteArray> leftBinaries({{location, "leftbinary"}});
const QHash<VcsLocation,QByteArray> rightBinaries({{location, "rightbinary"}});
const QHash<VcsLocation,QString> leftTexts({{location, "lefttext"}});
const QHash<VcsLocation,QString> rightTexts({{location, "righttext"}});
{
VcsDiff diffA;
setDiff(diffA,
type, contentType, diffString, baseDiff, depth, leftBinaries, rightBinaries, leftTexts, rightTexts);
VcsDiff diffB(diffA);
compareDiff(diffA,
type, contentType, diffString, baseDiff, depth, leftBinaries, rightBinaries, leftTexts, rightTexts);
compareDiff(diffB,
type, contentType, diffString, baseDiff, depth, leftBinaries, rightBinaries, leftTexts, rightTexts);
}
const VcsDiff::Type typeNew = VcsDiff::DiffUnified;
// test detach after changing A
{
VcsDiff diffA;
setDiff(diffA,
type, contentType, diffString, baseDiff, depth, leftBinaries, rightBinaries, leftTexts, rightTexts);
VcsDiff diffB(diffA);
// change a property of A
diffA.setType(typeNew);
compareDiff(diffA,
typeNew, contentType, diffString, baseDiff, depth, leftBinaries, rightBinaries, leftTexts, rightTexts);
compareDiff(diffB,
type, contentType, diffString, baseDiff, depth, leftBinaries, rightBinaries, leftTexts, rightTexts);
}
}
void TestVcsDiff::testAssignOperator()
{
// test plain copy
const VcsDiff::Type type = VcsDiff::DiffRaw;
const VcsDiff::Content contentType = VcsDiff::Binary;
const QString diffString("diff");
const QUrl baseDiff("git://1");
const uint depth = 1;
const VcsLocation location("server");
const QHash<VcsLocation,QByteArray> leftBinaries({{location, "leftbinary"}});
const QHash<VcsLocation,QByteArray> rightBinaries({{location, "rightbinary"}});
const QHash<VcsLocation,QString> leftTexts({{location, "lefttext"}});
const QHash<VcsLocation,QString> rightTexts({{location, "righttext"}});
{
VcsDiff diffA;
setDiff(diffA,
type, contentType, diffString, baseDiff, depth, leftBinaries, rightBinaries, leftTexts, rightTexts);