2022-08-19 15:59:36 +02:00
|
|
|
// Copyright (C) 2016 The Qt Company Ltd.
|
2022-12-21 10:12:09 +01:00
|
|
|
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
2013-02-15 12:49:50 +01:00
|
|
|
|
|
|
|
|
#include "diffeditorplugin.h"
|
|
|
|
|
#include "diffeditorconstants.h"
|
2015-01-30 16:59:25 +01:00
|
|
|
#include "diffeditorcontroller.h"
|
2014-02-13 16:43:28 +01:00
|
|
|
#include "diffeditordocument.h"
|
2013-06-17 13:55:31 +02:00
|
|
|
#include "diffeditorfactory.h"
|
2023-01-19 14:43:28 +01:00
|
|
|
#include "diffeditortr.h"
|
2013-02-15 12:49:50 +01:00
|
|
|
|
|
|
|
|
#include <coreplugin/actionmanager/actioncontainer.h>
|
|
|
|
|
#include <coreplugin/actionmanager/actionmanager.h>
|
2016-10-05 13:22:55 +02:00
|
|
|
#include <coreplugin/editormanager/documentmodel.h>
|
2013-02-15 12:49:50 +01:00
|
|
|
#include <coreplugin/editormanager/editormanager.h>
|
|
|
|
|
|
2023-04-25 15:32:10 +02:00
|
|
|
#include <extensionsystem/pluginmanager.h>
|
|
|
|
|
|
2016-10-18 13:14:40 +02:00
|
|
|
#include <texteditor/textdocument.h>
|
2016-10-05 13:22:55 +02:00
|
|
|
|
2022-12-15 17:14:56 +01:00
|
|
|
#include <utils/asynctask.h>
|
2018-08-29 14:36:47 +02:00
|
|
|
#include <utils/differ.h>
|
2023-01-12 13:13:09 +01:00
|
|
|
#include <utils/fileutils.h>
|
2015-01-30 14:33:39 +01:00
|
|
|
#include <utils/qtcassert.h>
|
|
|
|
|
|
2023-01-12 13:13:09 +01:00
|
|
|
#include <QAction>
|
|
|
|
|
#include <QMenu>
|
|
|
|
|
|
2016-10-18 13:19:07 +02:00
|
|
|
using namespace Core;
|
2020-02-05 15:50:46 +01:00
|
|
|
using namespace TextEditor;
|
2018-08-29 14:36:47 +02:00
|
|
|
using namespace Utils;
|
2016-10-18 13:19:07 +02:00
|
|
|
|
2013-02-21 17:03:00 +01:00
|
|
|
namespace DiffEditor {
|
2013-05-07 14:02:08 +02:00
|
|
|
namespace Internal {
|
|
|
|
|
|
2016-11-18 16:06:27 +01:00
|
|
|
class ReloadInput {
|
|
|
|
|
public:
|
2022-09-26 15:45:45 +02:00
|
|
|
std::array<QString, SideCount> text{};
|
2022-09-29 17:49:32 +02:00
|
|
|
DiffFileInfoArray fileInfo{};
|
2016-11-18 16:06:27 +01:00
|
|
|
FileData::FileOperation fileOperation = FileData::ChangeFile;
|
2018-05-14 14:22:39 +02:00
|
|
|
bool binaryFiles = false;
|
2016-11-18 16:06:27 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
class DiffFile
|
|
|
|
|
{
|
|
|
|
|
public:
|
|
|
|
|
DiffFile(bool ignoreWhitespace, int contextLineCount)
|
2018-05-03 14:48:28 +02:00
|
|
|
: m_contextLineCount(contextLineCount),
|
|
|
|
|
m_ignoreWhitespace(ignoreWhitespace)
|
2016-11-18 16:06:27 +01:00
|
|
|
{}
|
|
|
|
|
|
2023-02-11 23:21:58 +01:00
|
|
|
void operator()(QPromise<FileData> &promise, const ReloadInput &reloadInput) const
|
2016-11-18 16:06:27 +01:00
|
|
|
{
|
2022-12-15 17:14:56 +01:00
|
|
|
if (reloadInput.text[LeftSide] == reloadInput.text[RightSide])
|
2018-05-14 14:22:39 +02:00
|
|
|
return; // We show "No difference" in this case, regardless if it's binary or not
|
|
|
|
|
|
2023-02-11 23:21:58 +01:00
|
|
|
Differ differ(QFuture<void>(promise.future()));
|
2016-11-18 16:06:27 +01:00
|
|
|
|
2018-05-14 14:22:39 +02:00
|
|
|
FileData fileData;
|
2022-12-15 17:14:56 +01:00
|
|
|
if (!reloadInput.binaryFiles) {
|
2020-11-18 22:42:51 +01:00
|
|
|
const QList<Diff> diffList = Differ::cleanupSemantics(
|
2022-12-15 17:14:56 +01:00
|
|
|
differ.diff(reloadInput.text[LeftSide], reloadInput.text[RightSide]));
|
2018-05-14 14:22:39 +02:00
|
|
|
|
|
|
|
|
QList<Diff> leftDiffList;
|
|
|
|
|
QList<Diff> rightDiffList;
|
|
|
|
|
Differ::splitDiffList(diffList, &leftDiffList, &rightDiffList);
|
|
|
|
|
QList<Diff> outputLeftDiffList;
|
|
|
|
|
QList<Diff> outputRightDiffList;
|
|
|
|
|
|
|
|
|
|
if (m_ignoreWhitespace) {
|
|
|
|
|
const QList<Diff> leftIntermediate
|
|
|
|
|
= Differ::moveWhitespaceIntoEqualities(leftDiffList);
|
|
|
|
|
const QList<Diff> rightIntermediate
|
|
|
|
|
= Differ::moveWhitespaceIntoEqualities(rightDiffList);
|
|
|
|
|
Differ::ignoreWhitespaceBetweenEqualities(leftIntermediate, rightIntermediate,
|
|
|
|
|
&outputLeftDiffList, &outputRightDiffList);
|
|
|
|
|
} else {
|
|
|
|
|
outputLeftDiffList = leftDiffList;
|
|
|
|
|
outputRightDiffList = rightDiffList;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const ChunkData chunkData = DiffUtils::calculateOriginalData(
|
|
|
|
|
outputLeftDiffList, outputRightDiffList);
|
|
|
|
|
fileData = DiffUtils::calculateContextData(chunkData, m_contextLineCount, 0);
|
|
|
|
|
}
|
2022-12-15 17:14:56 +01:00
|
|
|
fileData.fileInfo = reloadInput.fileInfo;
|
|
|
|
|
fileData.fileOperation = reloadInput.fileOperation;
|
|
|
|
|
fileData.binaryFiles = reloadInput.binaryFiles;
|
2023-02-11 23:21:58 +01:00
|
|
|
promise.addResult(fileData);
|
2016-11-18 16:06:27 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private:
|
|
|
|
|
const int m_contextLineCount;
|
2018-05-03 14:48:28 +02:00
|
|
|
const bool m_ignoreWhitespace;
|
2016-11-18 16:06:27 +01:00
|
|
|
};
|
|
|
|
|
|
2016-10-05 13:22:55 +02:00
|
|
|
class DiffFilesController : public DiffEditorController
|
|
|
|
|
{
|
|
|
|
|
Q_OBJECT
|
|
|
|
|
public:
|
2016-10-18 13:19:07 +02:00
|
|
|
DiffFilesController(IDocument *document);
|
2016-10-05 13:22:55 +02:00
|
|
|
|
|
|
|
|
protected:
|
2016-11-18 16:06:27 +01:00
|
|
|
virtual QList<ReloadInput> reloadInputList() const = 0;
|
2016-10-05 13:22:55 +02:00
|
|
|
};
|
|
|
|
|
|
2016-10-18 13:19:07 +02:00
|
|
|
DiffFilesController::DiffFilesController(IDocument *document)
|
2016-10-05 13:22:55 +02:00
|
|
|
: DiffEditorController(document)
|
2016-11-18 16:06:27 +01:00
|
|
|
{
|
2023-01-19 14:43:28 +01:00
|
|
|
setDisplayName(Tr::tr("Diff"));
|
2022-12-15 17:14:56 +01:00
|
|
|
using namespace Tasking;
|
|
|
|
|
|
2023-02-02 23:32:26 +01:00
|
|
|
const TreeStorage<QList<std::optional<FileData>>> storage;
|
2022-12-15 17:14:56 +01:00
|
|
|
|
|
|
|
|
const auto setupTree = [this, storage](TaskTree &taskTree) {
|
2023-02-02 23:32:26 +01:00
|
|
|
QList<std::optional<FileData>> *outputList = storage.activeStorage();
|
2022-12-15 17:14:56 +01:00
|
|
|
|
|
|
|
|
const auto setupDiff = [this](AsyncTask<FileData> &async, const ReloadInput &reloadInput) {
|
2023-04-25 15:32:10 +02:00
|
|
|
async.setConcurrentCallData(
|
|
|
|
|
DiffFile(ignoreWhitespace(), contextLineCount()), reloadInput);
|
|
|
|
|
async.setFutureSynchronizer(ExtensionSystem::PluginManager::futureSynchronizer());
|
2022-12-15 17:14:56 +01:00
|
|
|
};
|
|
|
|
|
const auto onDiffDone = [outputList](const AsyncTask<FileData> &async, int i) {
|
2023-02-02 23:32:26 +01:00
|
|
|
if (async.isResultAvailable())
|
|
|
|
|
(*outputList)[i] = async.result();
|
2022-12-15 17:14:56 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const QList<ReloadInput> inputList = reloadInputList();
|
|
|
|
|
outputList->resize(inputList.size());
|
|
|
|
|
|
|
|
|
|
using namespace std::placeholders;
|
2023-02-02 23:32:26 +01:00
|
|
|
QList<TaskItem> tasks {parallel, optional};
|
2022-12-15 17:14:56 +01:00
|
|
|
for (int i = 0; i < inputList.size(); ++i) {
|
|
|
|
|
tasks.append(Async<FileData>(std::bind(setupDiff, _1, inputList.at(i)),
|
|
|
|
|
std::bind(onDiffDone, _1, i)));
|
|
|
|
|
}
|
|
|
|
|
taskTree.setupRoot(tasks);
|
|
|
|
|
};
|
|
|
|
|
const auto onTreeDone = [this, storage] {
|
2023-02-20 20:58:38 +01:00
|
|
|
const QList<std::optional<FileData>> &results = *storage;
|
2023-02-02 23:32:26 +01:00
|
|
|
QList<FileData> finalList;
|
|
|
|
|
for (const std::optional<FileData> &result : results) {
|
|
|
|
|
if (result.has_value())
|
|
|
|
|
finalList.append(*result);
|
|
|
|
|
}
|
|
|
|
|
setDiffFiles(finalList);
|
2022-12-15 17:14:56 +01:00
|
|
|
};
|
|
|
|
|
const auto onTreeError = [this, storage] {
|
|
|
|
|
setDiffFiles({});
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const Group root = {
|
|
|
|
|
Storage(storage),
|
|
|
|
|
Tree(setupTree),
|
|
|
|
|
OnGroupDone(onTreeDone),
|
|
|
|
|
OnGroupError(onTreeError)
|
|
|
|
|
};
|
|
|
|
|
setReloadRecipe(root);
|
2016-10-05 13:22:55 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
class DiffCurrentFileController : public DiffFilesController
|
|
|
|
|
{
|
|
|
|
|
Q_OBJECT
|
|
|
|
|
public:
|
2023-01-12 13:13:09 +01:00
|
|
|
DiffCurrentFileController(IDocument *document, const QString &fileName)
|
|
|
|
|
: DiffFilesController(document)
|
|
|
|
|
, m_fileName(fileName) {}
|
2016-10-05 13:22:55 +02:00
|
|
|
|
|
|
|
|
protected:
|
2016-11-18 16:06:27 +01:00
|
|
|
QList<ReloadInput> reloadInputList() const final;
|
2016-10-05 13:22:55 +02:00
|
|
|
|
|
|
|
|
private:
|
2016-11-17 10:27:55 +01:00
|
|
|
const QString m_fileName;
|
2016-10-05 13:22:55 +02:00
|
|
|
};
|
|
|
|
|
|
2016-11-18 16:06:27 +01:00
|
|
|
QList<ReloadInput> DiffCurrentFileController::reloadInputList() const
|
2016-10-05 13:22:55 +02:00
|
|
|
{
|
2016-11-18 16:06:27 +01:00
|
|
|
QList<ReloadInput> result;
|
2016-10-05 13:22:55 +02:00
|
|
|
|
2023-01-12 13:13:09 +01:00
|
|
|
auto textDocument = qobject_cast<TextDocument *>(
|
2021-05-18 07:57:14 +02:00
|
|
|
DocumentModel::documentForFilePath(FilePath::fromString(m_fileName)));
|
2016-10-05 13:22:55 +02:00
|
|
|
|
|
|
|
|
if (textDocument && textDocument->isModified()) {
|
|
|
|
|
QString errorString;
|
2022-06-03 15:19:02 +02:00
|
|
|
TextFileFormat format = textDocument->format();
|
2016-10-05 13:22:55 +02:00
|
|
|
|
|
|
|
|
QString leftText;
|
2023-01-12 13:13:09 +01:00
|
|
|
const TextFileFormat::ReadResult leftResult = TextFileFormat::readFile(
|
|
|
|
|
FilePath::fromString(m_fileName), format.codec, &leftText, &format, &errorString);
|
2016-10-05 13:22:55 +02:00
|
|
|
|
|
|
|
|
const QString rightText = textDocument->plainText();
|
|
|
|
|
|
2016-11-18 16:06:27 +01:00
|
|
|
ReloadInput reloadInput;
|
2022-09-26 15:45:45 +02:00
|
|
|
reloadInput.text = {leftText, rightText};
|
2023-01-19 14:43:28 +01:00
|
|
|
reloadInput.fileInfo = {DiffFileInfo(m_fileName, Tr::tr("Saved")),
|
|
|
|
|
DiffFileInfo(m_fileName, Tr::tr("Modified"))};
|
2022-09-26 15:45:45 +02:00
|
|
|
reloadInput.fileInfo[RightSide].patchBehaviour = DiffFileInfo::PatchEditor;
|
2022-06-03 15:19:02 +02:00
|
|
|
reloadInput.binaryFiles = (leftResult == TextFileFormat::ReadEncodingError);
|
2016-10-05 13:22:55 +02:00
|
|
|
|
2022-06-03 15:19:02 +02:00
|
|
|
if (leftResult == TextFileFormat::ReadIOError)
|
2016-11-18 16:06:27 +01:00
|
|
|
reloadInput.fileOperation = FileData::NewFile;
|
2016-10-05 13:22:55 +02:00
|
|
|
|
2016-11-18 16:06:27 +01:00
|
|
|
result << reloadInput;
|
2016-10-05 13:22:55 +02:00
|
|
|
}
|
|
|
|
|
|
2016-11-18 16:06:27 +01:00
|
|
|
return result;
|
2016-10-05 13:22:55 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/////////////////
|
|
|
|
|
|
2016-10-18 13:14:40 +02:00
|
|
|
class DiffOpenFilesController : public DiffFilesController
|
2014-02-13 16:43:28 +01:00
|
|
|
{
|
|
|
|
|
Q_OBJECT
|
|
|
|
|
public:
|
2023-01-12 13:13:09 +01:00
|
|
|
DiffOpenFilesController(IDocument *document) : DiffFilesController(document) {}
|
2016-10-05 13:22:55 +02:00
|
|
|
|
|
|
|
|
protected:
|
2016-11-18 16:06:27 +01:00
|
|
|
QList<ReloadInput> reloadInputList() const final;
|
2016-10-05 13:22:55 +02:00
|
|
|
};
|
|
|
|
|
|
2016-11-18 16:06:27 +01:00
|
|
|
QList<ReloadInput> DiffOpenFilesController::reloadInputList() const
|
2016-10-05 13:22:55 +02:00
|
|
|
{
|
2016-11-18 16:06:27 +01:00
|
|
|
QList<ReloadInput> result;
|
2016-10-05 13:22:55 +02:00
|
|
|
|
2016-11-18 16:06:27 +01:00
|
|
|
const QList<IDocument *> openedDocuments = DocumentModel::openedDocuments();
|
2016-10-05 13:22:55 +02:00
|
|
|
|
2017-12-06 21:30:57 +01:00
|
|
|
for (IDocument *doc : openedDocuments) {
|
2021-12-06 15:42:25 +01:00
|
|
|
QTC_ASSERT(doc, continue);
|
2023-01-12 13:13:09 +01:00
|
|
|
auto textDocument = qobject_cast<TextDocument *>(doc);
|
2016-10-05 13:22:55 +02:00
|
|
|
|
|
|
|
|
if (textDocument && textDocument->isModified()) {
|
|
|
|
|
QString errorString;
|
2022-06-03 15:19:02 +02:00
|
|
|
TextFileFormat format = textDocument->format();
|
2016-10-05 13:22:55 +02:00
|
|
|
|
|
|
|
|
QString leftText;
|
|
|
|
|
const QString fileName = textDocument->filePath().toString();
|
2022-06-03 15:19:02 +02:00
|
|
|
const TextFileFormat::ReadResult leftResult = TextFileFormat::readFile(
|
2021-05-18 07:57:14 +02:00
|
|
|
FilePath::fromString(fileName), format.codec, &leftText, &format, &errorString);
|
2016-10-05 13:22:55 +02:00
|
|
|
|
|
|
|
|
const QString rightText = textDocument->plainText();
|
|
|
|
|
|
2016-11-18 16:06:27 +01:00
|
|
|
ReloadInput reloadInput;
|
2022-09-26 15:45:45 +02:00
|
|
|
reloadInput.text = {leftText, rightText};
|
2023-01-19 14:43:28 +01:00
|
|
|
reloadInput.fileInfo = {DiffFileInfo(fileName, Tr::tr("Saved")),
|
|
|
|
|
DiffFileInfo(fileName, Tr::tr("Modified"))};
|
2022-09-26 15:45:45 +02:00
|
|
|
reloadInput.fileInfo[RightSide].patchBehaviour = DiffFileInfo::PatchEditor;
|
2022-06-03 15:19:02 +02:00
|
|
|
reloadInput.binaryFiles = (leftResult == TextFileFormat::ReadEncodingError);
|
2016-10-05 13:22:55 +02:00
|
|
|
|
2022-06-03 15:19:02 +02:00
|
|
|
if (leftResult == TextFileFormat::ReadIOError)
|
2016-11-18 16:06:27 +01:00
|
|
|
reloadInput.fileOperation = FileData::NewFile;
|
2016-10-05 13:22:55 +02:00
|
|
|
|
2016-11-18 16:06:27 +01:00
|
|
|
result << reloadInput;
|
2016-10-05 13:22:55 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2016-11-18 16:06:27 +01:00
|
|
|
return result;
|
2016-10-05 13:22:55 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/////////////////
|
|
|
|
|
|
2016-10-05 17:37:00 +02:00
|
|
|
class DiffModifiedFilesController : public DiffFilesController
|
|
|
|
|
{
|
|
|
|
|
Q_OBJECT
|
|
|
|
|
public:
|
2023-01-12 13:13:09 +01:00
|
|
|
DiffModifiedFilesController(IDocument *document, const QStringList &fileNames)
|
|
|
|
|
: DiffFilesController(document)
|
|
|
|
|
, m_fileNames(fileNames) {}
|
2016-10-05 17:37:00 +02:00
|
|
|
|
|
|
|
|
protected:
|
2016-11-18 16:06:27 +01:00
|
|
|
QList<ReloadInput> reloadInputList() const final;
|
2016-10-05 17:37:00 +02:00
|
|
|
|
|
|
|
|
private:
|
2016-11-17 10:27:55 +01:00
|
|
|
const QStringList m_fileNames;
|
2016-10-05 17:37:00 +02:00
|
|
|
};
|
|
|
|
|
|
2016-11-18 16:06:27 +01:00
|
|
|
QList<ReloadInput> DiffModifiedFilesController::reloadInputList() const
|
2016-10-05 17:37:00 +02:00
|
|
|
{
|
2016-11-18 16:06:27 +01:00
|
|
|
QList<ReloadInput> result;
|
2016-10-05 17:37:00 +02:00
|
|
|
|
2017-12-06 21:30:57 +01:00
|
|
|
for (const QString &fileName : m_fileNames) {
|
2023-01-12 13:13:09 +01:00
|
|
|
auto textDocument = qobject_cast<TextDocument *>(
|
2022-06-03 15:19:02 +02:00
|
|
|
DocumentModel::documentForFilePath(FilePath::fromString(fileName)));
|
2016-10-05 17:37:00 +02:00
|
|
|
|
|
|
|
|
if (textDocument && textDocument->isModified()) {
|
|
|
|
|
QString errorString;
|
2022-06-03 15:19:02 +02:00
|
|
|
TextFileFormat format = textDocument->format();
|
2016-10-05 17:37:00 +02:00
|
|
|
|
|
|
|
|
QString leftText;
|
|
|
|
|
const QString fileName = textDocument->filePath().toString();
|
2022-06-03 15:19:02 +02:00
|
|
|
const TextFileFormat::ReadResult leftResult = TextFileFormat::readFile(
|
2021-05-18 07:57:14 +02:00
|
|
|
FilePath::fromString(fileName), format.codec, &leftText, &format, &errorString);
|
2016-10-05 17:37:00 +02:00
|
|
|
|
|
|
|
|
const QString rightText = textDocument->plainText();
|
|
|
|
|
|
2016-11-18 16:06:27 +01:00
|
|
|
ReloadInput reloadInput;
|
2022-09-26 15:45:45 +02:00
|
|
|
reloadInput.text = {leftText, rightText};
|
2023-01-19 14:43:28 +01:00
|
|
|
reloadInput.fileInfo = {DiffFileInfo(fileName, Tr::tr("Saved")),
|
|
|
|
|
DiffFileInfo(fileName, Tr::tr("Modified"))};
|
2022-09-26 15:45:45 +02:00
|
|
|
reloadInput.fileInfo[RightSide].patchBehaviour = DiffFileInfo::PatchEditor;
|
2022-06-03 15:19:02 +02:00
|
|
|
reloadInput.binaryFiles = (leftResult == TextFileFormat::ReadEncodingError);
|
2016-10-05 17:37:00 +02:00
|
|
|
|
2022-06-03 15:19:02 +02:00
|
|
|
if (leftResult == TextFileFormat::ReadIOError)
|
2016-11-18 16:06:27 +01:00
|
|
|
reloadInput.fileOperation = FileData::NewFile;
|
2016-10-05 17:37:00 +02:00
|
|
|
|
2016-11-18 16:06:27 +01:00
|
|
|
result << reloadInput;
|
2016-10-05 17:37:00 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2016-11-18 16:06:27 +01:00
|
|
|
return result;
|
2016-10-05 17:37:00 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/////////////////
|
|
|
|
|
|
2016-10-05 13:22:55 +02:00
|
|
|
class DiffExternalFilesController : public DiffFilesController
|
|
|
|
|
{
|
|
|
|
|
Q_OBJECT
|
|
|
|
|
public:
|
2016-10-18 13:19:07 +02:00
|
|
|
DiffExternalFilesController(IDocument *document, const QString &leftFileName,
|
2023-01-12 13:13:09 +01:00
|
|
|
const QString &rightFileName)
|
|
|
|
|
: DiffFilesController(document)
|
|
|
|
|
, m_leftFileName(leftFileName)
|
|
|
|
|
, m_rightFileName(rightFileName) {}
|
2014-02-13 16:43:28 +01:00
|
|
|
|
|
|
|
|
protected:
|
2016-11-18 16:06:27 +01:00
|
|
|
QList<ReloadInput> reloadInputList() const final;
|
2014-02-13 16:43:28 +01:00
|
|
|
|
|
|
|
|
private:
|
2016-11-17 10:27:55 +01:00
|
|
|
const QString m_leftFileName;
|
|
|
|
|
const QString m_rightFileName;
|
2014-02-13 16:43:28 +01:00
|
|
|
};
|
|
|
|
|
|
2016-11-18 16:06:27 +01:00
|
|
|
QList<ReloadInput> DiffExternalFilesController::reloadInputList() const
|
2014-02-13 16:43:28 +01:00
|
|
|
{
|
2014-06-30 15:04:36 +02:00
|
|
|
QString errorString;
|
2022-06-03 15:19:02 +02:00
|
|
|
TextFileFormat format;
|
2016-10-18 13:19:07 +02:00
|
|
|
format.codec = EditorManager::defaultTextCodec();
|
2014-06-30 15:04:36 +02:00
|
|
|
|
|
|
|
|
QString leftText;
|
|
|
|
|
QString rightText;
|
2018-05-14 14:22:39 +02:00
|
|
|
|
2022-06-03 15:19:02 +02:00
|
|
|
const TextFileFormat::ReadResult leftResult = TextFileFormat::readFile(
|
2021-05-18 07:57:14 +02:00
|
|
|
FilePath::fromString(m_leftFileName), format.codec, &leftText, &format, &errorString);
|
2022-06-03 15:19:02 +02:00
|
|
|
const TextFileFormat::ReadResult rightResult = TextFileFormat::readFile(
|
2021-05-18 07:57:14 +02:00
|
|
|
FilePath::fromString(m_rightFileName), format.codec, &rightText, &format, &errorString);
|
2014-02-13 16:43:28 +01:00
|
|
|
|
2016-11-18 16:06:27 +01:00
|
|
|
ReloadInput reloadInput;
|
2022-09-26 15:45:45 +02:00
|
|
|
reloadInput.text = {leftText, rightText};
|
|
|
|
|
reloadInput.fileInfo[LeftSide].fileName = m_leftFileName;
|
|
|
|
|
reloadInput.fileInfo[RightSide].fileName = m_rightFileName;
|
2022-06-03 15:19:02 +02:00
|
|
|
reloadInput.binaryFiles = (leftResult == TextFileFormat::ReadEncodingError
|
|
|
|
|
|| rightResult == TextFileFormat::ReadEncodingError);
|
2018-05-14 14:22:39 +02:00
|
|
|
|
2022-06-03 15:19:02 +02:00
|
|
|
const bool leftFileExists = (leftResult != TextFileFormat::ReadIOError);
|
|
|
|
|
const bool rightFileExists = (rightResult != TextFileFormat::ReadIOError);
|
2016-07-25 13:09:06 +02:00
|
|
|
if (!leftFileExists && rightFileExists)
|
2016-11-18 16:06:27 +01:00
|
|
|
reloadInput.fileOperation = FileData::NewFile;
|
2016-07-25 13:09:06 +02:00
|
|
|
else if (leftFileExists && !rightFileExists)
|
2016-11-18 16:06:27 +01:00
|
|
|
reloadInput.fileOperation = FileData::DeleteFile;
|
2014-02-13 16:43:28 +01:00
|
|
|
|
2016-11-18 16:06:27 +01:00
|
|
|
QList<ReloadInput> result;
|
2016-10-05 13:22:55 +02:00
|
|
|
if (leftFileExists || rightFileExists)
|
2016-11-18 16:06:27 +01:00
|
|
|
result << reloadInput;
|
2014-02-13 16:43:28 +01:00
|
|
|
|
2016-11-18 16:06:27 +01:00
|
|
|
return result;
|
2014-02-13 16:43:28 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/////////////////
|
|
|
|
|
|
2016-10-18 13:14:40 +02:00
|
|
|
|
2023-01-12 13:13:09 +01:00
|
|
|
static TextDocument *currentTextDocument()
|
2016-10-18 13:14:40 +02:00
|
|
|
{
|
2023-01-12 13:13:09 +01:00
|
|
|
return qobject_cast<TextDocument *>(EditorManager::currentDocument());
|
2016-10-18 13:14:40 +02:00
|
|
|
}
|
|
|
|
|
|
2020-02-05 15:50:46 +01:00
|
|
|
DiffEditorServiceImpl::DiffEditorServiceImpl() = default;
|
2016-10-05 17:37:00 +02:00
|
|
|
|
2023-01-12 14:28:44 +01:00
|
|
|
template <typename Controller, typename... Args>
|
|
|
|
|
void reload(const QString &vcsId, const QString &displayName, Args &&...args)
|
2016-11-25 15:23:52 +01:00
|
|
|
{
|
|
|
|
|
auto const document = qobject_cast<DiffEditorDocument *>(
|
2023-01-12 14:28:44 +01:00
|
|
|
DiffEditorController::findOrCreateDocument(vcsId, displayName));
|
2016-11-25 15:23:52 +01:00
|
|
|
if (!document)
|
|
|
|
|
return;
|
|
|
|
|
if (!DiffEditorController::controller(document))
|
2023-01-12 14:28:44 +01:00
|
|
|
new Controller(document, std::forward<Args>(args)...);
|
2016-11-25 15:23:52 +01:00
|
|
|
EditorManager::activateEditorForDocument(document);
|
|
|
|
|
document->reload();
|
|
|
|
|
}
|
|
|
|
|
|
2023-01-12 14:28:44 +01:00
|
|
|
void DiffEditorServiceImpl::diffFiles(const QString &leftFileName, const QString &rightFileName)
|
2016-10-05 17:37:00 +02:00
|
|
|
{
|
2016-11-24 09:58:11 +01:00
|
|
|
const QString documentId = Constants::DIFF_EDITOR_PLUGIN
|
2023-01-12 14:28:44 +01:00
|
|
|
+ QLatin1String(".DiffFiles.") + leftFileName + QLatin1Char('.') + rightFileName;
|
2023-01-19 14:43:28 +01:00
|
|
|
const QString title = Tr::tr("Diff Files");
|
2023-01-12 14:28:44 +01:00
|
|
|
reload<DiffExternalFilesController>(documentId, title, leftFileName, rightFileName);
|
|
|
|
|
}
|
2016-10-05 17:37:00 +02:00
|
|
|
|
2023-01-12 14:28:44 +01:00
|
|
|
void DiffEditorServiceImpl::diffModifiedFiles(const QStringList &fileNames)
|
|
|
|
|
{
|
|
|
|
|
const QString documentId = Constants::DIFF_EDITOR_PLUGIN + QLatin1String(".DiffModifiedFiles");
|
2023-01-19 14:43:28 +01:00
|
|
|
const QString title = Tr::tr("Diff Modified Files");
|
2023-01-12 14:28:44 +01:00
|
|
|
reload<DiffModifiedFilesController>(documentId, title, fileNames);
|
2016-10-05 17:37:00 +02:00
|
|
|
}
|
|
|
|
|
|
2020-02-05 15:50:46 +01:00
|
|
|
class DiffEditorPluginPrivate : public QObject
|
2013-02-15 12:49:50 +01:00
|
|
|
{
|
2020-02-05 15:50:46 +01:00
|
|
|
public:
|
|
|
|
|
DiffEditorPluginPrivate();
|
|
|
|
|
|
|
|
|
|
void updateDiffCurrentFileAction();
|
|
|
|
|
void updateDiffOpenFilesAction();
|
|
|
|
|
void diffCurrentFile();
|
|
|
|
|
void diffOpenFiles();
|
|
|
|
|
void diffExternalFiles();
|
2013-02-15 12:49:50 +01:00
|
|
|
|
2020-02-05 15:50:46 +01:00
|
|
|
QAction *m_diffCurrentFileAction = nullptr;
|
|
|
|
|
QAction *m_diffOpenFilesAction = nullptr;
|
|
|
|
|
|
2022-09-22 13:48:54 +02:00
|
|
|
DiffEditorFactory m_editorFactory;
|
|
|
|
|
DiffEditorServiceImpl m_service;
|
2020-02-05 15:50:46 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
DiffEditorPluginPrivate::DiffEditorPluginPrivate()
|
|
|
|
|
{
|
2013-02-15 12:49:50 +01:00
|
|
|
//register actions
|
2023-01-12 13:13:09 +01:00
|
|
|
ActionContainer *toolsContainer = ActionManager::actionContainer(Core::Constants::M_TOOLS);
|
2022-01-24 17:06:54 +01:00
|
|
|
toolsContainer->insertGroup(Core::Constants::G_TOOLS_DEBUG, Constants::G_TOOLS_DIFF);
|
2016-10-18 13:19:07 +02:00
|
|
|
ActionContainer *diffContainer = ActionManager::createMenu("Diff");
|
2023-01-19 14:43:28 +01:00
|
|
|
diffContainer->menu()->setTitle(Tr::tr("&Diff"));
|
2016-10-05 13:22:55 +02:00
|
|
|
toolsContainer->addMenu(diffContainer, Constants::G_TOOLS_DIFF);
|
|
|
|
|
|
2023-01-19 14:43:28 +01:00
|
|
|
m_diffCurrentFileAction = new QAction(Tr::tr("Diff Current File"), this);
|
2016-10-18 13:19:07 +02:00
|
|
|
Command *diffCurrentFileCommand = ActionManager::registerAction(m_diffCurrentFileAction, "DiffEditor.DiffCurrentFile");
|
2023-01-19 14:43:28 +01:00
|
|
|
diffCurrentFileCommand->setDefaultKeySequence(QKeySequence(useMacShortcuts ? Tr::tr("Meta+H") : Tr::tr("Ctrl+H")));
|
2020-02-05 15:50:46 +01:00
|
|
|
connect(m_diffCurrentFileAction, &QAction::triggered, this, &DiffEditorPluginPrivate::diffCurrentFile);
|
2016-10-05 13:22:55 +02:00
|
|
|
diffContainer->addAction(diffCurrentFileCommand);
|
2013-02-15 12:49:50 +01:00
|
|
|
|
2023-01-19 14:43:28 +01:00
|
|
|
m_diffOpenFilesAction = new QAction(Tr::tr("Diff Open Files"), this);
|
2016-10-18 13:19:07 +02:00
|
|
|
Command *diffOpenFilesCommand = ActionManager::registerAction(m_diffOpenFilesAction, "DiffEditor.DiffOpenFiles");
|
2023-01-19 14:43:28 +01:00
|
|
|
diffOpenFilesCommand->setDefaultKeySequence(QKeySequence(useMacShortcuts ? Tr::tr("Meta+Shift+H") : Tr::tr("Ctrl+Shift+H")));
|
2020-02-05 15:50:46 +01:00
|
|
|
connect(m_diffOpenFilesAction, &QAction::triggered, this, &DiffEditorPluginPrivate::diffOpenFiles);
|
2016-10-18 13:14:40 +02:00
|
|
|
diffContainer->addAction(diffOpenFilesCommand);
|
2016-10-05 13:22:55 +02:00
|
|
|
|
2023-01-19 14:43:28 +01:00
|
|
|
QAction *diffExternalFilesAction = new QAction(Tr::tr("Diff External Files..."), this);
|
2016-10-18 13:19:07 +02:00
|
|
|
Command *diffExternalFilesCommand = ActionManager::registerAction(diffExternalFilesAction, "DiffEditor.DiffExternalFiles");
|
2020-02-05 15:50:46 +01:00
|
|
|
connect(diffExternalFilesAction, &QAction::triggered, this, &DiffEditorPluginPrivate::diffExternalFiles);
|
2016-10-05 13:22:55 +02:00
|
|
|
diffContainer->addAction(diffExternalFilesCommand);
|
|
|
|
|
|
2016-10-18 13:19:07 +02:00
|
|
|
connect(EditorManager::instance(), &EditorManager::currentEditorChanged,
|
2020-02-05 15:50:46 +01:00
|
|
|
this, &DiffEditorPluginPrivate::updateDiffCurrentFileAction);
|
2016-10-18 13:19:07 +02:00
|
|
|
connect(EditorManager::instance(), &EditorManager::currentDocumentStateChanged,
|
2023-01-12 13:13:09 +01:00
|
|
|
this, &DiffEditorPluginPrivate::updateDiffCurrentFileAction);
|
2016-10-18 13:19:07 +02:00
|
|
|
connect(EditorManager::instance(), &EditorManager::editorOpened,
|
2023-01-12 13:13:09 +01:00
|
|
|
this, &DiffEditorPluginPrivate::updateDiffOpenFilesAction);
|
2016-10-18 13:19:07 +02:00
|
|
|
connect(EditorManager::instance(), &EditorManager::editorsClosed,
|
2023-01-12 13:13:09 +01:00
|
|
|
this, &DiffEditorPluginPrivate::updateDiffOpenFilesAction);
|
2016-10-18 13:19:07 +02:00
|
|
|
connect(EditorManager::instance(), &EditorManager::documentStateChanged,
|
2023-01-12 13:13:09 +01:00
|
|
|
this, &DiffEditorPluginPrivate::updateDiffOpenFilesAction);
|
2016-10-18 13:14:40 +02:00
|
|
|
|
|
|
|
|
updateDiffCurrentFileAction();
|
|
|
|
|
updateDiffOpenFilesAction();
|
2013-02-15 12:49:50 +01:00
|
|
|
}
|
|
|
|
|
|
2020-02-05 15:50:46 +01:00
|
|
|
void DiffEditorPluginPrivate::updateDiffCurrentFileAction()
|
2016-10-05 13:22:55 +02:00
|
|
|
{
|
2016-10-18 13:14:40 +02:00
|
|
|
auto textDocument = currentTextDocument();
|
|
|
|
|
const bool enabled = textDocument && textDocument->isModified();
|
|
|
|
|
m_diffCurrentFileAction->setEnabled(enabled);
|
2016-10-05 13:22:55 +02:00
|
|
|
}
|
|
|
|
|
|
2020-02-05 15:50:46 +01:00
|
|
|
void DiffEditorPluginPrivate::updateDiffOpenFilesAction()
|
2016-10-05 13:22:55 +02:00
|
|
|
{
|
2022-06-03 15:19:02 +02:00
|
|
|
const bool enabled = anyOf(DocumentModel::openedDocuments(), [](IDocument *doc) {
|
2021-12-06 15:42:25 +01:00
|
|
|
QTC_ASSERT(doc, return false);
|
2023-01-12 13:13:09 +01:00
|
|
|
return doc->isModified() && qobject_cast<TextDocument *>(doc);
|
2016-10-18 13:14:40 +02:00
|
|
|
});
|
|
|
|
|
m_diffOpenFilesAction->setEnabled(enabled);
|
2016-10-05 13:22:55 +02:00
|
|
|
}
|
|
|
|
|
|
2020-02-05 15:50:46 +01:00
|
|
|
void DiffEditorPluginPrivate::diffCurrentFile()
|
2016-10-05 13:22:55 +02:00
|
|
|
{
|
2016-10-18 13:14:40 +02:00
|
|
|
auto textDocument = currentTextDocument();
|
|
|
|
|
if (!textDocument)
|
2016-10-05 13:22:55 +02:00
|
|
|
return;
|
|
|
|
|
|
2016-10-18 13:14:40 +02:00
|
|
|
const QString fileName = textDocument->filePath().toString();
|
2016-10-05 13:22:55 +02:00
|
|
|
if (fileName.isEmpty())
|
|
|
|
|
return;
|
|
|
|
|
|
2023-01-12 14:28:44 +01:00
|
|
|
const QString documentId = Constants::DIFF_EDITOR_PLUGIN + QLatin1String(".Diff.") + fileName;
|
2023-01-19 14:43:28 +01:00
|
|
|
const QString title = Tr::tr("Diff \"%1\"").arg(fileName);
|
2023-01-12 14:28:44 +01:00
|
|
|
reload<DiffCurrentFileController>(documentId, title, fileName);
|
2016-10-05 13:22:55 +02:00
|
|
|
}
|
|
|
|
|
|
2020-02-05 15:50:46 +01:00
|
|
|
void DiffEditorPluginPrivate::diffOpenFiles()
|
2016-10-05 13:22:55 +02:00
|
|
|
{
|
2023-01-12 14:28:44 +01:00
|
|
|
const QString documentId = Constants::DIFF_EDITOR_PLUGIN + QLatin1String(".DiffOpenFiles");
|
2023-01-19 14:43:28 +01:00
|
|
|
const QString title = Tr::tr("Diff Open Files");
|
2023-01-12 14:28:44 +01:00
|
|
|
reload<DiffOpenFilesController>(documentId, title);
|
2016-10-05 13:22:55 +02:00
|
|
|
}
|
|
|
|
|
|
2020-02-05 15:50:46 +01:00
|
|
|
void DiffEditorPluginPrivate::diffExternalFiles()
|
2013-02-15 12:49:50 +01:00
|
|
|
{
|
2023-01-19 14:43:28 +01:00
|
|
|
const FilePath filePath1 = FileUtils::getOpenFilePath(nullptr, Tr::tr("Select First File for Diff"));
|
2021-07-26 17:41:28 +02:00
|
|
|
if (filePath1.isEmpty())
|
2013-02-15 12:49:50 +01:00
|
|
|
return;
|
2021-07-26 17:41:28 +02:00
|
|
|
if (EditorManager::skipOpeningBigTextFile(filePath1))
|
2016-11-23 13:58:23 +01:00
|
|
|
return;
|
2023-01-19 14:43:28 +01:00
|
|
|
const FilePath filePath2 = FileUtils::getOpenFilePath(nullptr, Tr::tr("Select Second File for Diff"));
|
2021-07-26 17:41:28 +02:00
|
|
|
if (filePath2.isEmpty())
|
2013-02-15 12:49:50 +01:00
|
|
|
return;
|
2021-07-26 17:41:28 +02:00
|
|
|
if (EditorManager::skipOpeningBigTextFile(filePath2))
|
2016-11-23 13:58:23 +01:00
|
|
|
return;
|
2013-02-15 12:49:50 +01:00
|
|
|
|
2021-07-26 17:41:28 +02:00
|
|
|
const QString documentId = QLatin1String(Constants::DIFF_EDITOR_PLUGIN)
|
|
|
|
|
+ ".DiffExternalFiles." + filePath1.toString() + '.' + filePath2.toString();
|
2023-01-19 14:43:28 +01:00
|
|
|
const QString title = Tr::tr("Diff \"%1\", \"%2\"").arg(filePath1.toString(), filePath2.toString());
|
2023-01-12 14:28:44 +01:00
|
|
|
reload<DiffExternalFilesController>(documentId, title, filePath1.toString(), filePath2.toString());
|
2013-02-15 12:49:50 +01:00
|
|
|
}
|
|
|
|
|
|
2022-09-22 13:48:54 +02:00
|
|
|
static DiffEditorPlugin *s_instance = nullptr;
|
|
|
|
|
|
|
|
|
|
DiffEditorPlugin::DiffEditorPlugin()
|
|
|
|
|
{
|
|
|
|
|
s_instance = this;
|
|
|
|
|
}
|
|
|
|
|
|
2020-02-05 15:50:46 +01:00
|
|
|
DiffEditorPlugin::~DiffEditorPlugin()
|
|
|
|
|
{
|
|
|
|
|
delete d;
|
2022-09-22 13:48:54 +02:00
|
|
|
s_instance = nullptr;
|
2020-02-05 15:50:46 +01:00
|
|
|
}
|
|
|
|
|
|
2023-01-20 12:28:36 +01:00
|
|
|
void DiffEditorPlugin::initialize()
|
2020-02-05 15:50:46 +01:00
|
|
|
{
|
|
|
|
|
d = new DiffEditorPluginPrivate;
|
|
|
|
|
}
|
|
|
|
|
|
2014-02-13 16:43:28 +01:00
|
|
|
} // namespace Internal
|
|
|
|
|
} // namespace DiffEditor
|
|
|
|
|
|
|
|
|
|
#ifdef WITH_TESTS
|
|
|
|
|
|
|
|
|
|
#include <QTest>
|
|
|
|
|
|
|
|
|
|
#include "diffutils.h"
|
|
|
|
|
|
|
|
|
|
Q_DECLARE_METATYPE(DiffEditor::ChunkData)
|
2015-07-24 16:48:04 +03:00
|
|
|
Q_DECLARE_METATYPE(DiffEditor::FileData)
|
2017-11-29 21:36:30 +01:00
|
|
|
Q_DECLARE_METATYPE(DiffEditor::ChunkSelection)
|
2014-02-13 16:43:28 +01:00
|
|
|
|
2014-07-26 22:57:42 +03:00
|
|
|
static inline QString _(const char *string) { return QString::fromLatin1(string); }
|
|
|
|
|
|
2014-02-13 16:43:28 +01:00
|
|
|
void DiffEditor::Internal::DiffEditorPlugin::testMakePatch_data()
|
2013-02-15 12:49:50 +01:00
|
|
|
{
|
2014-02-13 16:43:28 +01:00
|
|
|
QTest::addColumn<ChunkData>("sourceChunk");
|
|
|
|
|
QTest::addColumn<bool>("lastChunk");
|
|
|
|
|
QTest::addColumn<QString>("patchText");
|
|
|
|
|
|
2017-12-06 21:30:57 +01:00
|
|
|
const QString fileName = "a.txt";
|
|
|
|
|
const QString header = "--- " + fileName + "\n+++ " + fileName + '\n';
|
2014-02-13 16:43:28 +01:00
|
|
|
|
|
|
|
|
QList<RowData> rows;
|
2014-07-26 22:57:42 +03:00
|
|
|
rows << RowData(_("ABCD"), TextLineData::Separator);
|
|
|
|
|
rows << RowData(_("EFGH"));
|
2014-02-13 16:43:28 +01:00
|
|
|
ChunkData chunk;
|
|
|
|
|
chunk.rows = rows;
|
2017-12-06 21:30:57 +01:00
|
|
|
QString patchText = header + "@@ -1,2 +1,1 @@\n"
|
|
|
|
|
"-ABCD\n"
|
|
|
|
|
" EFGH\n";
|
2014-07-09 12:37:47 +02:00
|
|
|
QTest::newRow("Simple not a last chunk") << chunk
|
|
|
|
|
<< false
|
|
|
|
|
<< patchText;
|
|
|
|
|
|
|
|
|
|
///////////
|
|
|
|
|
|
|
|
|
|
// chunk the same here
|
2017-12-06 21:30:57 +01:00
|
|
|
patchText = header + "@@ -1,2 +1,1 @@\n"
|
|
|
|
|
"-ABCD\n"
|
|
|
|
|
" EFGH\n"
|
|
|
|
|
"\\ No newline at end of file\n";
|
2014-07-09 12:37:47 +02:00
|
|
|
|
|
|
|
|
QTest::newRow("Simple last chunk") << chunk
|
2014-02-13 16:43:28 +01:00
|
|
|
<< true
|
|
|
|
|
<< patchText;
|
|
|
|
|
|
|
|
|
|
///////////
|
|
|
|
|
|
|
|
|
|
rows.clear();
|
2014-07-26 22:57:42 +03:00
|
|
|
rows << RowData(_("ABCD"));
|
|
|
|
|
rows << RowData(_(""), TextLineData::Separator);
|
2014-02-13 16:43:28 +01:00
|
|
|
chunk.rows = rows;
|
2017-12-06 21:30:57 +01:00
|
|
|
patchText = header + "@@ -1,1 +1,1 @@\n"
|
|
|
|
|
"-ABCD\n"
|
|
|
|
|
"+ABCD\n"
|
|
|
|
|
"\\ No newline at end of file\n";
|
2014-02-13 16:43:28 +01:00
|
|
|
|
2014-07-09 12:37:47 +02:00
|
|
|
QTest::newRow("EOL in last line removed") << chunk
|
2014-02-13 16:43:28 +01:00
|
|
|
<< true
|
|
|
|
|
<< patchText;
|
|
|
|
|
|
|
|
|
|
///////////
|
|
|
|
|
|
|
|
|
|
// chunk the same here
|
2017-12-06 21:30:57 +01:00
|
|
|
patchText = header + "@@ -1,2 +1,1 @@\n"
|
|
|
|
|
" ABCD\n"
|
|
|
|
|
"-\n";
|
2014-02-13 16:43:28 +01:00
|
|
|
|
2014-07-09 12:37:47 +02:00
|
|
|
QTest::newRow("Last empty line removed") << chunk
|
2014-02-13 16:43:28 +01:00
|
|
|
<< false
|
|
|
|
|
<< patchText;
|
|
|
|
|
|
|
|
|
|
///////////
|
|
|
|
|
|
2014-08-06 15:03:26 +03:00
|
|
|
rows.clear();
|
|
|
|
|
rows << RowData(_("ABCD"));
|
|
|
|
|
rows << RowData(_(""), TextLineData::Separator);
|
|
|
|
|
rows << RowData(_(""), TextLineData::Separator);
|
|
|
|
|
chunk.rows = rows;
|
2017-12-06 21:30:57 +01:00
|
|
|
patchText = header + "@@ -1,2 +1,1 @@\n"
|
|
|
|
|
"-ABCD\n"
|
|
|
|
|
"-\n"
|
|
|
|
|
"+ABCD\n"
|
|
|
|
|
"\\ No newline at end of file\n";
|
2014-08-06 15:03:26 +03:00
|
|
|
|
|
|
|
|
QTest::newRow("Two last EOLs removed") << chunk
|
|
|
|
|
<< true
|
|
|
|
|
<< patchText;
|
|
|
|
|
|
|
|
|
|
///////////
|
|
|
|
|
|
2014-02-13 16:43:28 +01:00
|
|
|
rows.clear();
|
2014-07-26 22:57:42 +03:00
|
|
|
rows << RowData(_("ABCD"));
|
|
|
|
|
rows << RowData(TextLineData::Separator, _(""));
|
2014-02-13 16:43:28 +01:00
|
|
|
chunk.rows = rows;
|
2017-12-06 21:30:57 +01:00
|
|
|
patchText = header + "@@ -1,1 +1,1 @@\n"
|
|
|
|
|
"-ABCD\n"
|
|
|
|
|
"\\ No newline at end of file\n"
|
|
|
|
|
"+ABCD\n";
|
2014-02-13 16:43:28 +01:00
|
|
|
|
2014-07-09 12:37:47 +02:00
|
|
|
QTest::newRow("EOL to last line added") << chunk
|
2014-02-13 16:43:28 +01:00
|
|
|
<< true
|
|
|
|
|
<< patchText;
|
|
|
|
|
|
|
|
|
|
///////////
|
|
|
|
|
|
|
|
|
|
// chunk the same here
|
2017-12-06 21:30:57 +01:00
|
|
|
patchText = header + "@@ -1,1 +1,2 @@\n"
|
|
|
|
|
" ABCD\n"
|
|
|
|
|
"+\n";
|
2014-02-13 16:43:28 +01:00
|
|
|
|
2014-07-09 12:37:47 +02:00
|
|
|
QTest::newRow("Last empty line added") << chunk
|
2014-02-13 16:43:28 +01:00
|
|
|
<< false
|
|
|
|
|
<< patchText;
|
|
|
|
|
|
|
|
|
|
///////////
|
|
|
|
|
|
|
|
|
|
rows.clear();
|
2014-07-26 22:57:42 +03:00
|
|
|
rows << RowData(_("ABCD"), _("EFGH"));
|
2014-02-13 16:43:28 +01:00
|
|
|
chunk.rows = rows;
|
2017-12-06 21:30:57 +01:00
|
|
|
patchText = header + "@@ -1,1 +1,1 @@\n"
|
|
|
|
|
"-ABCD\n"
|
|
|
|
|
"+EFGH\n";
|
2014-02-13 16:43:28 +01:00
|
|
|
|
|
|
|
|
QTest::newRow("Last line with a newline modified") << chunk
|
2014-07-09 12:37:47 +02:00
|
|
|
<< false
|
2014-02-13 16:43:28 +01:00
|
|
|
<< patchText;
|
|
|
|
|
|
|
|
|
|
///////////
|
|
|
|
|
|
2014-07-09 12:37:47 +02:00
|
|
|
rows.clear();
|
2014-07-26 22:57:42 +03:00
|
|
|
rows << RowData(_("ABCD"), _("EFGH"));
|
|
|
|
|
rows << RowData(_(""));
|
2014-07-09 12:37:47 +02:00
|
|
|
chunk.rows = rows;
|
2017-12-06 21:30:57 +01:00
|
|
|
patchText = header + "@@ -1,2 +1,2 @@\n"
|
|
|
|
|
"-ABCD\n"
|
|
|
|
|
"+EFGH\n"
|
|
|
|
|
" \n";
|
2014-02-13 16:43:28 +01:00
|
|
|
QTest::newRow("Not a last line with a newline modified") << chunk
|
|
|
|
|
<< false
|
|
|
|
|
<< patchText;
|
|
|
|
|
|
|
|
|
|
///////////
|
|
|
|
|
|
|
|
|
|
rows.clear();
|
2014-07-26 22:57:42 +03:00
|
|
|
rows << RowData(_("ABCD"), _("EFGH"));
|
2014-02-13 16:43:28 +01:00
|
|
|
chunk.rows = rows;
|
2017-12-06 21:30:57 +01:00
|
|
|
patchText = header + "@@ -1,1 +1,1 @@\n"
|
|
|
|
|
"-ABCD\n"
|
|
|
|
|
"\\ No newline at end of file\n"
|
|
|
|
|
"+EFGH\n"
|
|
|
|
|
"\\ No newline at end of file\n";
|
2014-02-13 16:43:28 +01:00
|
|
|
|
|
|
|
|
QTest::newRow("Last line without a newline modified") << chunk
|
|
|
|
|
<< true
|
|
|
|
|
<< patchText;
|
|
|
|
|
|
|
|
|
|
///////////
|
|
|
|
|
|
|
|
|
|
// chunk the same here
|
2017-12-06 21:30:57 +01:00
|
|
|
patchText = header + "@@ -1,1 +1,1 @@\n"
|
|
|
|
|
"-ABCD\n"
|
|
|
|
|
"+EFGH\n";
|
2014-02-13 16:43:28 +01:00
|
|
|
QTest::newRow("Not a last line without a newline modified") << chunk
|
|
|
|
|
<< false
|
|
|
|
|
<< patchText;
|
|
|
|
|
|
|
|
|
|
///////////
|
|
|
|
|
|
|
|
|
|
rows.clear();
|
2014-07-26 22:57:42 +03:00
|
|
|
rows << RowData(_("ABCD"), _("EFGH"));
|
|
|
|
|
rows << RowData(_("IJKL"));
|
2014-02-13 16:43:28 +01:00
|
|
|
chunk.rows = rows;
|
2017-12-06 21:30:57 +01:00
|
|
|
patchText = header + "@@ -1,2 +1,2 @@\n"
|
|
|
|
|
"-ABCD\n"
|
|
|
|
|
"+EFGH\n"
|
|
|
|
|
" IJKL\n"
|
|
|
|
|
"\\ No newline at end of file\n";
|
2014-02-13 16:43:28 +01:00
|
|
|
|
|
|
|
|
QTest::newRow("Last but one line modified, last line without a newline")
|
|
|
|
|
<< chunk
|
|
|
|
|
<< true
|
|
|
|
|
<< patchText;
|
|
|
|
|
|
|
|
|
|
///////////
|
|
|
|
|
|
|
|
|
|
// chunk the same here
|
2017-12-06 21:30:57 +01:00
|
|
|
patchText = header + "@@ -1,2 +1,2 @@\n"
|
|
|
|
|
"-ABCD\n"
|
|
|
|
|
"+EFGH\n"
|
|
|
|
|
" IJKL\n";
|
2014-02-13 16:43:28 +01:00
|
|
|
|
|
|
|
|
QTest::newRow("Last but one line modified, last line with a newline")
|
|
|
|
|
<< chunk
|
|
|
|
|
<< false
|
|
|
|
|
<< patchText;
|
2014-08-06 15:03:26 +03:00
|
|
|
|
|
|
|
|
///////////
|
|
|
|
|
|
|
|
|
|
rows.clear();
|
|
|
|
|
rows << RowData(_("ABCD"));
|
|
|
|
|
rows << RowData(TextLineData::Separator, _(""));
|
|
|
|
|
rows << RowData(_(""), _("EFGH"));
|
|
|
|
|
chunk.rows = rows;
|
2017-12-06 21:30:57 +01:00
|
|
|
patchText = header + "@@ -1,1 +1,3 @@\n"
|
|
|
|
|
" ABCD\n"
|
|
|
|
|
"+\n"
|
|
|
|
|
"+EFGH\n"
|
|
|
|
|
"\\ No newline at end of file\n";
|
2014-08-06 15:03:26 +03:00
|
|
|
|
|
|
|
|
QTest::newRow("Blank line followed by No newline")
|
|
|
|
|
<< chunk
|
|
|
|
|
<< true
|
|
|
|
|
<< patchText;
|
2013-02-15 12:49:50 +01:00
|
|
|
}
|
|
|
|
|
|
2014-02-13 16:43:28 +01:00
|
|
|
void DiffEditor::Internal::DiffEditorPlugin::testMakePatch()
|
|
|
|
|
{
|
|
|
|
|
QFETCH(ChunkData, sourceChunk);
|
|
|
|
|
QFETCH(bool, lastChunk);
|
|
|
|
|
QFETCH(QString, patchText);
|
|
|
|
|
|
2018-01-16 22:45:10 +02:00
|
|
|
const QString fileName = "a.txt";
|
|
|
|
|
const QString result = DiffUtils::makePatch(sourceChunk, fileName, fileName, lastChunk);
|
2014-02-13 16:43:28 +01:00
|
|
|
|
2014-07-09 12:37:47 +02:00
|
|
|
QCOMPARE(result, patchText);
|
|
|
|
|
|
2023-02-11 23:21:58 +01:00
|
|
|
const std::optional<QList<FileData>> resultList = DiffUtils::readPatch(result);
|
|
|
|
|
const bool ok = resultList.has_value();
|
2014-07-09 12:37:47 +02:00
|
|
|
|
|
|
|
|
QVERIFY(ok);
|
2023-02-11 23:21:58 +01:00
|
|
|
QCOMPARE(resultList->count(), 1);
|
|
|
|
|
for (int i = 0; i < resultList->count(); i++) {
|
|
|
|
|
const FileData &resultFileData = resultList->at(i);
|
2022-09-26 15:28:00 +02:00
|
|
|
QCOMPARE(resultFileData.fileInfo[LeftSide].fileName, fileName);
|
|
|
|
|
QCOMPARE(resultFileData.fileInfo[RightSide].fileName, fileName);
|
2014-07-09 12:37:47 +02:00
|
|
|
QCOMPARE(resultFileData.chunks.count(), 1);
|
|
|
|
|
for (int j = 0; j < resultFileData.chunks.count(); j++) {
|
|
|
|
|
const ChunkData &resultChunkData = resultFileData.chunks.at(j);
|
2022-09-26 14:15:40 +02:00
|
|
|
QCOMPARE(resultChunkData.startingLineNumber[LeftSide], sourceChunk.startingLineNumber[LeftSide]);
|
|
|
|
|
QCOMPARE(resultChunkData.startingLineNumber[RightSide], sourceChunk.startingLineNumber[RightSide]);
|
2014-07-09 12:37:47 +02:00
|
|
|
QCOMPARE(resultChunkData.contextChunk, sourceChunk.contextChunk);
|
|
|
|
|
QCOMPARE(resultChunkData.rows.count(), sourceChunk.rows.count());
|
|
|
|
|
for (int k = 0; k < sourceChunk.rows.count(); k++) {
|
|
|
|
|
const RowData &sourceRowData = sourceChunk.rows.at(k);
|
|
|
|
|
const RowData &resultRowData = resultChunkData.rows.at(k);
|
|
|
|
|
QCOMPARE(resultRowData.equal, sourceRowData.equal);
|
2022-09-26 14:49:52 +02:00
|
|
|
QCOMPARE(resultRowData.line[LeftSide].text, sourceRowData.line[LeftSide].text);
|
|
|
|
|
QCOMPARE(resultRowData.line[LeftSide].textLineType, sourceRowData.line[LeftSide].textLineType);
|
|
|
|
|
QCOMPARE(resultRowData.line[RightSide].text, sourceRowData.line[RightSide].text);
|
|
|
|
|
QCOMPARE(resultRowData.line[RightSide].textLineType, sourceRowData.line[RightSide].textLineType);
|
2014-07-09 12:37:47 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2014-02-13 16:43:28 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void DiffEditor::Internal::DiffEditorPlugin::testReadPatch_data()
|
|
|
|
|
{
|
|
|
|
|
QTest::addColumn<QString>("sourcePatch");
|
2022-09-27 15:13:33 +02:00
|
|
|
QTest::addColumn<QList<FileData>>("fileDataList");
|
2014-02-13 16:43:28 +01:00
|
|
|
|
2017-12-06 21:30:57 +01:00
|
|
|
QString patch = "diff --git a/src/plugins/diffeditor/diffeditor.cpp b/src/plugins/diffeditor/diffeditor.cpp\n"
|
|
|
|
|
"index eab9e9b..082c135 100644\n"
|
|
|
|
|
"--- a/src/plugins/diffeditor/diffeditor.cpp\n"
|
|
|
|
|
"+++ b/src/plugins/diffeditor/diffeditor.cpp\n"
|
|
|
|
|
"@@ -187,9 +187,6 @@ void DiffEditor::ctor()\n"
|
|
|
|
|
" m_controller = m_document->controller();\n"
|
|
|
|
|
" m_guiController = new DiffEditorGuiController(m_controller, this);\n"
|
|
|
|
|
" \n"
|
|
|
|
|
"-// m_sideBySideEditor->setDiffEditorGuiController(m_guiController);\n"
|
|
|
|
|
"-// m_unifiedEditor->setDiffEditorGuiController(m_guiController);\n"
|
|
|
|
|
"-\n"
|
|
|
|
|
" connect(m_controller, SIGNAL(cleared(QString)),\n"
|
|
|
|
|
" this, SLOT(slotCleared(QString)));\n"
|
|
|
|
|
" connect(m_controller, SIGNAL(diffContentsChanged(QList<DiffEditorController::DiffFilesContents>,QString)),\n"
|
|
|
|
|
"diff --git a/src/plugins/diffeditor/diffutils.cpp b/src/plugins/diffeditor/diffutils.cpp\n"
|
|
|
|
|
"index 2f641c9..f8ff795 100644\n"
|
|
|
|
|
"--- a/src/plugins/diffeditor/diffutils.cpp\n"
|
|
|
|
|
"+++ b/src/plugins/diffeditor/diffutils.cpp\n"
|
|
|
|
|
"@@ -464,5 +464,12 @@ QString DiffUtils::makePatch(const ChunkData &chunkData,\n"
|
|
|
|
|
" return diffText;\n"
|
|
|
|
|
" }\n"
|
|
|
|
|
" \n"
|
|
|
|
|
"+FileData DiffUtils::makeFileData(const QString &patch)\n"
|
|
|
|
|
"+{\n"
|
|
|
|
|
"+ FileData fileData;\n"
|
|
|
|
|
"+\n"
|
|
|
|
|
"+ return fileData;\n"
|
|
|
|
|
"+}\n"
|
|
|
|
|
"+\n"
|
|
|
|
|
" } // namespace Internal\n"
|
|
|
|
|
" } // namespace DiffEditor\n"
|
|
|
|
|
"diff --git a/new b/new\n"
|
|
|
|
|
"new file mode 100644\n"
|
|
|
|
|
"index 0000000..257cc56\n"
|
|
|
|
|
"--- /dev/null\n"
|
|
|
|
|
"+++ b/new\n"
|
|
|
|
|
"@@ -0,0 +1 @@\n"
|
|
|
|
|
"+foo\n"
|
|
|
|
|
"diff --git a/deleted b/deleted\n"
|
|
|
|
|
"deleted file mode 100644\n"
|
|
|
|
|
"index 257cc56..0000000\n"
|
|
|
|
|
"--- a/deleted\n"
|
|
|
|
|
"+++ /dev/null\n"
|
|
|
|
|
"@@ -1 +0,0 @@\n"
|
|
|
|
|
"-foo\n"
|
|
|
|
|
"diff --git a/empty b/empty\n"
|
|
|
|
|
"new file mode 100644\n"
|
|
|
|
|
"index 0000000..e69de29\n"
|
|
|
|
|
"diff --git a/empty b/empty\n"
|
|
|
|
|
"deleted file mode 100644\n"
|
|
|
|
|
"index e69de29..0000000\n"
|
|
|
|
|
"diff --git a/file a.txt b/file b.txt\n"
|
|
|
|
|
"similarity index 99%\n"
|
|
|
|
|
"copy from file a.txt\n"
|
|
|
|
|
"copy to file b.txt\n"
|
|
|
|
|
"index 1234567..9876543\n"
|
|
|
|
|
"--- a/file a.txt\n"
|
|
|
|
|
"+++ b/file b.txt\n"
|
|
|
|
|
"@@ -20,3 +20,3 @@\n"
|
|
|
|
|
" A\n"
|
|
|
|
|
"-B\n"
|
|
|
|
|
"+C\n"
|
|
|
|
|
" D\n"
|
|
|
|
|
"diff --git a/file a.txt b/file b.txt\n"
|
|
|
|
|
"similarity index 99%\n"
|
|
|
|
|
"rename from file a.txt\n"
|
|
|
|
|
"rename to file b.txt\n"
|
|
|
|
|
"diff --git a/file.txt b/file.txt\n"
|
|
|
|
|
"old mode 100644\n"
|
|
|
|
|
"new mode 100755\n"
|
|
|
|
|
"index 1234567..9876543\n"
|
|
|
|
|
"--- a/file.txt\n"
|
|
|
|
|
"+++ b/file.txt\n"
|
|
|
|
|
"@@ -20,3 +20,3 @@\n"
|
|
|
|
|
" A\n"
|
|
|
|
|
"-B\n"
|
|
|
|
|
"+C\n"
|
|
|
|
|
" D\n"
|
|
|
|
|
;
|
2014-02-13 16:43:28 +01:00
|
|
|
|
|
|
|
|
FileData fileData1;
|
2022-09-26 15:28:00 +02:00
|
|
|
fileData1.fileInfo = {DiffFileInfo("src/plugins/diffeditor/diffeditor.cpp", "eab9e9b"),
|
|
|
|
|
DiffFileInfo("src/plugins/diffeditor/diffeditor.cpp", "082c135")};
|
2014-02-13 16:43:28 +01:00
|
|
|
ChunkData chunkData1;
|
2022-09-26 14:15:40 +02:00
|
|
|
chunkData1.startingLineNumber = {186, 186};
|
2014-02-13 16:43:28 +01:00
|
|
|
QList<RowData> rows1;
|
2014-07-26 22:57:42 +03:00
|
|
|
rows1 << RowData(_(" m_controller = m_document->controller();"));
|
|
|
|
|
rows1 << RowData(_(" m_guiController = new DiffEditorGuiController(m_controller, this);"));
|
|
|
|
|
rows1 << RowData(_(""));
|
|
|
|
|
rows1 << RowData(_("// m_sideBySideEditor->setDiffEditorGuiController(m_guiController);"), TextLineData::Separator);
|
|
|
|
|
rows1 << RowData(_("// m_unifiedEditor->setDiffEditorGuiController(m_guiController);"), TextLineData::Separator);
|
|
|
|
|
rows1 << RowData(_(""), TextLineData::Separator);
|
|
|
|
|
rows1 << RowData(_(" connect(m_controller, SIGNAL(cleared(QString)),"));
|
|
|
|
|
rows1 << RowData(_(" this, SLOT(slotCleared(QString)));"));
|
|
|
|
|
rows1 << RowData(_(" connect(m_controller, SIGNAL(diffContentsChanged(QList<DiffEditorController::DiffFilesContents>,QString)),"));
|
2014-02-13 16:43:28 +01:00
|
|
|
chunkData1.rows = rows1;
|
2014-07-26 22:57:42 +03:00
|
|
|
fileData1.chunks << chunkData1;
|
2014-02-13 16:43:28 +01:00
|
|
|
|
|
|
|
|
FileData fileData2;
|
2022-09-26 15:28:00 +02:00
|
|
|
fileData2.fileInfo = {DiffFileInfo(_("src/plugins/diffeditor/diffutils.cpp"), _("2f641c9")),
|
|
|
|
|
DiffFileInfo(_("src/plugins/diffeditor/diffutils.cpp"), _("f8ff795"))};
|
2014-02-13 16:43:28 +01:00
|
|
|
ChunkData chunkData2;
|
2022-09-26 14:15:40 +02:00
|
|
|
chunkData2.startingLineNumber = {463, 463};
|
2014-02-13 16:43:28 +01:00
|
|
|
QList<RowData> rows2;
|
2014-07-26 22:57:42 +03:00
|
|
|
rows2 << RowData(_(" return diffText;"));
|
|
|
|
|
rows2 << RowData(_("}"));
|
|
|
|
|
rows2 << RowData(_(""));
|
|
|
|
|
rows2 << RowData(TextLineData::Separator, _("FileData DiffUtils::makeFileData(const QString &patch)"));
|
|
|
|
|
rows2 << RowData(TextLineData::Separator, _("{"));
|
|
|
|
|
rows2 << RowData(TextLineData::Separator, _(" FileData fileData;"));
|
|
|
|
|
rows2 << RowData(TextLineData::Separator, _(""));
|
|
|
|
|
rows2 << RowData(TextLineData::Separator, _(" return fileData;"));
|
|
|
|
|
rows2 << RowData(TextLineData::Separator, _("}"));
|
|
|
|
|
rows2 << RowData(TextLineData::Separator, _(""));
|
|
|
|
|
rows2 << RowData(_("} // namespace Internal"));
|
|
|
|
|
rows2 << RowData(_("} // namespace DiffEditor"));
|
2014-02-13 16:43:28 +01:00
|
|
|
chunkData2.rows = rows2;
|
2014-07-26 22:57:42 +03:00
|
|
|
fileData2.chunks << chunkData2;
|
2014-02-13 16:43:28 +01:00
|
|
|
|
2014-06-08 23:31:46 +03:00
|
|
|
FileData fileData3;
|
2022-09-26 15:28:00 +02:00
|
|
|
fileData3.fileInfo = {DiffFileInfo("new", "0000000"), DiffFileInfo("new", "257cc56")};
|
2014-07-07 14:26:41 +02:00
|
|
|
fileData3.fileOperation = FileData::NewFile;
|
2014-06-08 23:31:46 +03:00
|
|
|
ChunkData chunkData3;
|
2022-09-26 14:15:40 +02:00
|
|
|
chunkData3.startingLineNumber = {-1, 0};
|
2014-06-08 23:31:46 +03:00
|
|
|
QList<RowData> rows3;
|
2014-07-26 22:57:42 +03:00
|
|
|
rows3 << RowData(TextLineData::Separator, _("foo"));
|
2014-06-08 23:31:46 +03:00
|
|
|
TextLineData textLineData3(TextLineData::TextLine);
|
2014-07-26 22:57:42 +03:00
|
|
|
rows3 << RowData(TextLineData::Separator, textLineData3);
|
2014-06-08 23:31:46 +03:00
|
|
|
chunkData3.rows = rows3;
|
2014-07-26 22:57:42 +03:00
|
|
|
fileData3.chunks << chunkData3;
|
2014-06-08 23:31:46 +03:00
|
|
|
|
|
|
|
|
FileData fileData4;
|
2022-09-26 15:28:00 +02:00
|
|
|
fileData4.fileInfo = {DiffFileInfo("deleted", "257cc56"), DiffFileInfo("deleted", "0000000")};
|
2014-07-07 14:26:41 +02:00
|
|
|
fileData4.fileOperation = FileData::DeleteFile;
|
2014-06-08 23:31:46 +03:00
|
|
|
ChunkData chunkData4;
|
2022-09-26 14:15:40 +02:00
|
|
|
chunkData4.startingLineNumber = {0, -1};
|
2014-06-08 23:31:46 +03:00
|
|
|
QList<RowData> rows4;
|
2014-07-26 22:57:42 +03:00
|
|
|
rows4 << RowData(_("foo"), TextLineData::Separator);
|
2014-06-08 23:31:46 +03:00
|
|
|
TextLineData textLineData4(TextLineData::TextLine);
|
2014-07-26 22:57:42 +03:00
|
|
|
rows4 << RowData(textLineData4, TextLineData::Separator);
|
2014-06-08 23:31:46 +03:00
|
|
|
chunkData4.rows = rows4;
|
2014-07-26 22:57:42 +03:00
|
|
|
fileData4.chunks << chunkData4;
|
2014-06-08 23:31:46 +03:00
|
|
|
|
2014-06-08 23:34:01 +03:00
|
|
|
FileData fileData5;
|
2022-09-26 15:28:00 +02:00
|
|
|
fileData5.fileInfo = {DiffFileInfo("empty", "0000000"), DiffFileInfo("empty", "e69de29")};
|
2014-07-07 14:26:41 +02:00
|
|
|
fileData5.fileOperation = FileData::NewFile;
|
2014-06-08 23:34:01 +03:00
|
|
|
|
|
|
|
|
FileData fileData6;
|
2022-09-26 15:28:00 +02:00
|
|
|
fileData6.fileInfo = {DiffFileInfo("empty", "e69de29"), DiffFileInfo("empty", "0000000")};
|
2014-07-07 14:26:41 +02:00
|
|
|
fileData6.fileOperation = FileData::DeleteFile;
|
|
|
|
|
|
|
|
|
|
FileData fileData7;
|
2022-09-26 15:28:00 +02:00
|
|
|
fileData7.fileInfo = {DiffFileInfo("file a.txt", "1234567"),
|
|
|
|
|
DiffFileInfo("file b.txt", "9876543")};
|
2014-07-07 14:26:41 +02:00
|
|
|
fileData7.fileOperation = FileData::CopyFile;
|
|
|
|
|
ChunkData chunkData7;
|
2022-09-26 14:15:40 +02:00
|
|
|
chunkData7.startingLineNumber = {19, 19};
|
2014-07-07 14:26:41 +02:00
|
|
|
QList<RowData> rows7;
|
2014-07-26 22:57:42 +03:00
|
|
|
rows7 << RowData(_("A"));
|
|
|
|
|
rows7 << RowData(_("B"), _("C"));
|
|
|
|
|
rows7 << RowData(_("D"));
|
2014-07-07 14:26:41 +02:00
|
|
|
chunkData7.rows = rows7;
|
2014-07-26 22:57:42 +03:00
|
|
|
fileData7.chunks << chunkData7;
|
2014-07-07 14:26:41 +02:00
|
|
|
|
|
|
|
|
FileData fileData8;
|
2022-09-26 15:28:00 +02:00
|
|
|
fileData8.fileInfo = {DiffFileInfo("file a.txt"), DiffFileInfo("file b.txt")};
|
2014-07-07 14:26:41 +02:00
|
|
|
fileData8.fileOperation = FileData::RenameFile;
|
2014-06-08 23:34:01 +03:00
|
|
|
|
2015-08-24 20:30:18 +03:00
|
|
|
FileData fileData9;
|
2022-09-26 15:28:00 +02:00
|
|
|
fileData9.fileInfo = {DiffFileInfo("file.txt", "1234567"), DiffFileInfo("file.txt", "9876543")};
|
2015-08-24 20:30:18 +03:00
|
|
|
fileData9.chunks << chunkData7;
|
2014-07-09 12:37:47 +02:00
|
|
|
QList<FileData> fileDataList1;
|
2015-08-24 20:30:18 +03:00
|
|
|
fileDataList1 << fileData1 << fileData2 << fileData3 << fileData4 << fileData5
|
|
|
|
|
<< fileData6 << fileData7 << fileData8 << fileData9;
|
2014-02-13 16:43:28 +01:00
|
|
|
|
|
|
|
|
QTest::newRow("Git patch") << patch
|
2014-07-09 12:37:47 +02:00
|
|
|
<< fileDataList1;
|
|
|
|
|
|
|
|
|
|
//////////////
|
|
|
|
|
|
2017-12-06 21:30:57 +01:00
|
|
|
patch = "diff --git a/file foo.txt b/file foo.txt\n"
|
|
|
|
|
"index 1234567..9876543 100644\n"
|
|
|
|
|
"--- a/file foo.txt\n"
|
|
|
|
|
"+++ b/file foo.txt\n"
|
|
|
|
|
"@@ -50,4 +50,5 @@ void DiffEditor::ctor()\n"
|
|
|
|
|
" A\n"
|
|
|
|
|
" B\n"
|
|
|
|
|
" C\n"
|
|
|
|
|
"+\n";
|
|
|
|
|
|
2022-09-26 15:28:00 +02:00
|
|
|
fileData1.fileInfo = {DiffFileInfo("file foo.txt", "1234567"),
|
|
|
|
|
DiffFileInfo("file foo.txt", "9876543")};
|
2014-07-09 12:37:47 +02:00
|
|
|
fileData1.fileOperation = FileData::ChangeFile;
|
2022-09-26 14:15:40 +02:00
|
|
|
chunkData1.startingLineNumber = {49, 49};
|
2014-07-09 12:37:47 +02:00
|
|
|
rows1.clear();
|
2014-07-26 22:57:42 +03:00
|
|
|
rows1 << RowData(_("A"));
|
|
|
|
|
rows1 << RowData(_("B"));
|
|
|
|
|
rows1 << RowData(_("C"));
|
|
|
|
|
rows1 << RowData(TextLineData::Separator, _(""));
|
2014-07-09 12:37:47 +02:00
|
|
|
chunkData1.rows = rows1;
|
|
|
|
|
fileData1.chunks.clear();
|
2014-07-26 22:57:42 +03:00
|
|
|
fileData1.chunks << chunkData1;
|
2014-07-09 12:37:47 +02:00
|
|
|
|
|
|
|
|
QList<FileData> fileDataList2;
|
|
|
|
|
fileDataList2 << fileData1;
|
|
|
|
|
|
|
|
|
|
QTest::newRow("Added line") << patch
|
|
|
|
|
<< fileDataList2;
|
|
|
|
|
|
|
|
|
|
//////////////
|
|
|
|
|
|
2017-12-06 21:30:57 +01:00
|
|
|
patch = "diff --git a/file foo.txt b/file foo.txt\n"
|
|
|
|
|
"index 1234567..9876543 100644\n"
|
|
|
|
|
"--- a/file foo.txt\n"
|
|
|
|
|
"+++ b/file foo.txt\n"
|
|
|
|
|
"@@ -1,1 +1,1 @@\n"
|
|
|
|
|
"-ABCD\n"
|
|
|
|
|
"\\ No newline at end of file\n"
|
|
|
|
|
"+ABCD\n";
|
|
|
|
|
|
2022-09-26 15:28:00 +02:00
|
|
|
fileData1.fileInfo = {DiffFileInfo("file foo.txt", "1234567"),
|
|
|
|
|
DiffFileInfo("file foo.txt", "9876543")};
|
2014-07-09 12:37:47 +02:00
|
|
|
fileData1.fileOperation = FileData::ChangeFile;
|
2022-09-26 14:15:40 +02:00
|
|
|
chunkData1.startingLineNumber = {0, 0};
|
2014-07-09 12:37:47 +02:00
|
|
|
rows1.clear();
|
2014-07-26 22:57:42 +03:00
|
|
|
rows1 << RowData(_("ABCD"));
|
|
|
|
|
rows1 << RowData(TextLineData::Separator, _(""));
|
2014-07-09 12:37:47 +02:00
|
|
|
chunkData1.rows = rows1;
|
|
|
|
|
fileData1.chunks.clear();
|
2014-07-26 22:57:42 +03:00
|
|
|
fileData1.chunks << chunkData1;
|
2014-07-09 12:37:47 +02:00
|
|
|
|
|
|
|
|
QList<FileData> fileDataList3;
|
|
|
|
|
fileDataList3 << fileData1;
|
|
|
|
|
|
|
|
|
|
QTest::newRow("Last newline added to a line without newline") << patch
|
|
|
|
|
<< fileDataList3;
|
2014-07-28 12:15:01 +03:00
|
|
|
|
2017-12-06 21:30:57 +01:00
|
|
|
patch = "diff --git a/difftest.txt b/difftest.txt\n"
|
|
|
|
|
"index 1234567..9876543 100644\n"
|
|
|
|
|
"--- a/difftest.txt\n"
|
|
|
|
|
"+++ b/difftest.txt\n"
|
|
|
|
|
"@@ -2,5 +2,5 @@ void func()\n"
|
|
|
|
|
" A\n"
|
|
|
|
|
" B\n"
|
|
|
|
|
"-C\n"
|
|
|
|
|
"+Z\n"
|
|
|
|
|
" D\n"
|
|
|
|
|
" \n"
|
|
|
|
|
"@@ -9,2 +9,4 @@ void OtherFunc()\n"
|
|
|
|
|
" \n"
|
|
|
|
|
" D\n"
|
|
|
|
|
"+E\n"
|
|
|
|
|
"+F\n"
|
|
|
|
|
;
|
|
|
|
|
|
2022-09-26 15:28:00 +02:00
|
|
|
fileData1.fileInfo = {DiffFileInfo("difftest.txt", "1234567"),
|
|
|
|
|
DiffFileInfo("difftest.txt", "9876543")};
|
2014-07-28 12:15:01 +03:00
|
|
|
fileData1.fileOperation = FileData::ChangeFile;
|
2022-09-26 14:15:40 +02:00
|
|
|
chunkData1.startingLineNumber = {1, 1};
|
2014-07-28 12:15:01 +03:00
|
|
|
rows1.clear();
|
|
|
|
|
rows1 << RowData(_("A"));
|
|
|
|
|
rows1 << RowData(_("B"));
|
|
|
|
|
rows1 << RowData(_("C"), _("Z"));
|
|
|
|
|
rows1 << RowData(_("D"));
|
|
|
|
|
rows1 << RowData(_(""));
|
|
|
|
|
chunkData1.rows = rows1;
|
|
|
|
|
|
2022-09-26 14:15:40 +02:00
|
|
|
chunkData2.startingLineNumber = {8, 8};
|
2014-07-28 12:15:01 +03:00
|
|
|
rows2.clear();
|
|
|
|
|
rows2 << RowData(_(""));
|
|
|
|
|
rows2 << RowData(_("D"));
|
|
|
|
|
rows2 << RowData(TextLineData::Separator, _("E"));
|
|
|
|
|
rows2 << RowData(TextLineData::Separator, _("F"));
|
|
|
|
|
chunkData2.rows = rows2;
|
|
|
|
|
fileData1.chunks.clear();
|
|
|
|
|
fileData1.chunks << chunkData1;
|
|
|
|
|
fileData1.chunks << chunkData2;
|
|
|
|
|
|
|
|
|
|
QList<FileData> fileDataList4;
|
|
|
|
|
fileDataList4 << fileData1;
|
|
|
|
|
|
|
|
|
|
QTest::newRow("2 chunks - first ends with blank line") << patch
|
|
|
|
|
<< fileDataList4;
|
2014-08-06 15:03:26 +03:00
|
|
|
|
|
|
|
|
//////////////
|
|
|
|
|
|
2017-12-06 21:30:57 +01:00
|
|
|
patch = "diff --git a/file foo.txt b/file foo.txt\n"
|
|
|
|
|
"index 1234567..9876543 100644\n"
|
|
|
|
|
"--- a/file foo.txt\n"
|
|
|
|
|
"+++ b/file foo.txt\n"
|
|
|
|
|
"@@ -1,1 +1,3 @@ void DiffEditor::ctor()\n"
|
|
|
|
|
" ABCD\n"
|
|
|
|
|
"+\n"
|
|
|
|
|
"+EFGH\n"
|
|
|
|
|
"\\ No newline at end of file\n";
|
|
|
|
|
|
2022-09-26 15:28:00 +02:00
|
|
|
fileData1.fileInfo = {DiffFileInfo("file foo.txt", "1234567"),
|
|
|
|
|
DiffFileInfo("file foo.txt", "9876543")};
|
2014-08-06 15:03:26 +03:00
|
|
|
fileData1.fileOperation = FileData::ChangeFile;
|
2022-09-26 14:15:40 +02:00
|
|
|
chunkData1.startingLineNumber = {0, 0};
|
2014-08-06 15:03:26 +03:00
|
|
|
rows1.clear();
|
|
|
|
|
rows1 << RowData(_("ABCD"));
|
|
|
|
|
rows1 << RowData(TextLineData::Separator, _(""));
|
|
|
|
|
rows1 << RowData(_(""), _("EFGH"));
|
|
|
|
|
chunkData1.rows = rows1;
|
|
|
|
|
fileData1.chunks.clear();
|
|
|
|
|
fileData1.chunks << chunkData1;
|
|
|
|
|
|
|
|
|
|
QList<FileData> fileDataList5;
|
|
|
|
|
fileDataList5 << fileData1;
|
|
|
|
|
|
|
|
|
|
QTest::newRow("Blank line followed by No newline") << patch
|
|
|
|
|
<< fileDataList5;
|
2014-09-29 12:14:15 +03:00
|
|
|
|
|
|
|
|
//////////////
|
|
|
|
|
|
|
|
|
|
// Based on 953cdb97
|
2017-12-06 21:30:57 +01:00
|
|
|
patch = "diff --git a/src/plugins/texteditor/basetextdocument.h b/src/plugins/texteditor/textdocument.h\n"
|
|
|
|
|
"similarity index 100%\n"
|
|
|
|
|
"rename from src/plugins/texteditor/basetextdocument.h\n"
|
|
|
|
|
"rename to src/plugins/texteditor/textdocument.h\n"
|
|
|
|
|
"diff --git a/src/plugins/texteditor/basetextdocumentlayout.cpp b/src/plugins/texteditor/textdocumentlayout.cpp\n"
|
|
|
|
|
"similarity index 79%\n"
|
|
|
|
|
"rename from src/plugins/texteditor/basetextdocumentlayout.cpp\n"
|
|
|
|
|
"rename to src/plugins/texteditor/textdocumentlayout.cpp\n"
|
|
|
|
|
"index 0121933..01cc3a0 100644\n"
|
|
|
|
|
"--- a/src/plugins/texteditor/basetextdocumentlayout.cpp\n"
|
|
|
|
|
"+++ b/src/plugins/texteditor/textdocumentlayout.cpp\n"
|
|
|
|
|
"@@ -2,5 +2,5 @@ void func()\n"
|
|
|
|
|
" A\n"
|
|
|
|
|
" B\n"
|
|
|
|
|
"-C\n"
|
|
|
|
|
"+Z\n"
|
|
|
|
|
" D\n"
|
|
|
|
|
" \n"
|
|
|
|
|
;
|
2014-09-29 12:14:15 +03:00
|
|
|
|
2022-09-27 15:13:33 +02:00
|
|
|
fileData1 = {};
|
2022-09-26 15:28:00 +02:00
|
|
|
fileData1.fileInfo = {DiffFileInfo("src/plugins/texteditor/basetextdocument.h"),
|
|
|
|
|
DiffFileInfo("src/plugins/texteditor/textdocument.h")};
|
2014-09-29 12:14:15 +03:00
|
|
|
fileData1.fileOperation = FileData::RenameFile;
|
2022-09-27 15:13:33 +02:00
|
|
|
fileData2 = {};
|
2022-09-26 15:28:00 +02:00
|
|
|
fileData2.fileInfo = {DiffFileInfo("src/plugins/texteditor/basetextdocumentlayout.cpp", "0121933"),
|
|
|
|
|
DiffFileInfo("src/plugins/texteditor/textdocumentlayout.cpp", "01cc3a0")};
|
2014-09-29 12:14:15 +03:00
|
|
|
fileData2.fileOperation = FileData::RenameFile;
|
2022-09-26 14:15:40 +02:00
|
|
|
chunkData2.startingLineNumber = {1, 1};
|
2014-09-29 12:14:15 +03:00
|
|
|
rows2.clear();
|
|
|
|
|
rows2 << RowData(_("A"));
|
|
|
|
|
rows2 << RowData(_("B"));
|
|
|
|
|
rows2 << RowData(_("C"), _("Z"));
|
|
|
|
|
rows2 << RowData(_("D"));
|
|
|
|
|
rows2 << RowData(_(""));
|
|
|
|
|
chunkData2.rows = rows2;
|
|
|
|
|
fileData2.chunks.clear();
|
|
|
|
|
fileData2.chunks << chunkData2;
|
|
|
|
|
|
|
|
|
|
QList<FileData> fileDataList6;
|
|
|
|
|
fileDataList6 << fileData1 << fileData2;
|
|
|
|
|
|
|
|
|
|
QTest::newRow("Multiple renames") << patch
|
|
|
|
|
<< fileDataList6;
|
|
|
|
|
|
2014-11-02 22:10:15 +02:00
|
|
|
//////////////
|
|
|
|
|
|
|
|
|
|
// Dirty submodule
|
2017-12-06 21:30:57 +01:00
|
|
|
patch = "diff --git a/src/shared/qbs b/src/shared/qbs\n"
|
|
|
|
|
"--- a/src/shared/qbs\n"
|
|
|
|
|
"+++ b/src/shared/qbs\n"
|
|
|
|
|
"@@ -1 +1 @@\n"
|
|
|
|
|
"-Subproject commit eda76354077a427d692fee05479910de31040d3f\n"
|
|
|
|
|
"+Subproject commit eda76354077a427d692fee05479910de31040d3f-dirty\n"
|
|
|
|
|
;
|
2022-09-27 15:13:33 +02:00
|
|
|
fileData1 = {};
|
2022-09-26 15:28:00 +02:00
|
|
|
fileData1.fileInfo = {DiffFileInfo("src/shared/qbs"), DiffFileInfo("src/shared/qbs")};
|
2022-09-26 14:15:40 +02:00
|
|
|
chunkData1.startingLineNumber = {0, 0};
|
2014-11-02 22:10:15 +02:00
|
|
|
rows1.clear();
|
|
|
|
|
rows1 << RowData(_("Subproject commit eda76354077a427d692fee05479910de31040d3f"),
|
|
|
|
|
_("Subproject commit eda76354077a427d692fee05479910de31040d3f-dirty"));
|
|
|
|
|
chunkData1.rows = rows1;
|
|
|
|
|
fileData1.chunks.clear();
|
|
|
|
|
fileData1.chunks << chunkData1;
|
|
|
|
|
|
|
|
|
|
QList<FileData> fileDataList7;
|
|
|
|
|
fileDataList7 << fileData1;
|
|
|
|
|
QTest::newRow("Dirty submodule") << patch
|
|
|
|
|
<< fileDataList7;
|
2014-11-06 13:23:40 +01:00
|
|
|
|
2017-06-16 13:45:43 +02:00
|
|
|
//////////////
|
2017-12-06 21:30:57 +01:00
|
|
|
patch = "diff --git a/demos/arthurplugin/arthurplugin.pro b/demos/arthurplugin/arthurplugin.pro\n"
|
|
|
|
|
"new file mode 100644\n"
|
|
|
|
|
"index 0000000..c5132b4\n"
|
|
|
|
|
"--- /dev/null\n"
|
|
|
|
|
"+++ b/demos/arthurplugin/arthurplugin.pro\n"
|
|
|
|
|
"@@ -0,0 +1 @@\n"
|
|
|
|
|
"+XXX\n"
|
|
|
|
|
"diff --git a/demos/arthurplugin/bg1.jpg b/demos/arthurplugin/bg1.jpg\n"
|
|
|
|
|
"new file mode 100644\n"
|
|
|
|
|
"index 0000000..dfc7cee\n"
|
|
|
|
|
"Binary files /dev/null and b/demos/arthurplugin/bg1.jpg differ\n"
|
|
|
|
|
"diff --git a/demos/arthurplugin/flower.jpg b/demos/arthurplugin/flower.jpg\n"
|
|
|
|
|
"new file mode 100644\n"
|
|
|
|
|
"index 0000000..f8e022c\n"
|
|
|
|
|
"Binary files /dev/null and b/demos/arthurplugin/flower.jpg differ\n"
|
|
|
|
|
;
|
2017-06-16 13:45:43 +02:00
|
|
|
|
2022-09-27 15:13:33 +02:00
|
|
|
fileData1 = {};
|
2022-09-26 15:28:00 +02:00
|
|
|
fileData1.fileInfo = {DiffFileInfo("demos/arthurplugin/arthurplugin.pro", "0000000"),
|
|
|
|
|
DiffFileInfo("demos/arthurplugin/arthurplugin.pro", "c5132b4")};
|
2017-06-16 13:45:43 +02:00
|
|
|
fileData1.fileOperation = FileData::NewFile;
|
2022-09-27 15:13:33 +02:00
|
|
|
chunkData1 = {};
|
2022-09-26 14:15:40 +02:00
|
|
|
chunkData1.startingLineNumber = {-1, 0};
|
2017-06-16 13:45:43 +02:00
|
|
|
rows1.clear();
|
|
|
|
|
rows1 << RowData(TextLineData::Separator, _("XXX"));
|
|
|
|
|
rows1 << RowData(TextLineData::Separator, TextLineData(TextLineData::TextLine));
|
|
|
|
|
chunkData1.rows = rows1;
|
|
|
|
|
fileData1.chunks << chunkData1;
|
2022-09-27 15:13:33 +02:00
|
|
|
fileData2 = {};
|
2022-09-26 15:28:00 +02:00
|
|
|
fileData2.fileInfo = {DiffFileInfo("demos/arthurplugin/bg1.jpg", "0000000"),
|
|
|
|
|
DiffFileInfo("demos/arthurplugin/bg1.jpg", "dfc7cee")};
|
2017-06-16 13:45:43 +02:00
|
|
|
fileData2.fileOperation = FileData::NewFile;
|
|
|
|
|
fileData2.binaryFiles = true;
|
2022-09-27 15:13:33 +02:00
|
|
|
fileData3 = {};
|
2022-09-26 15:28:00 +02:00
|
|
|
fileData3.fileInfo = {DiffFileInfo("demos/arthurplugin/flower.jpg", "0000000"),
|
|
|
|
|
DiffFileInfo("demos/arthurplugin/flower.jpg", "f8e022c")};
|
2017-06-16 13:45:43 +02:00
|
|
|
fileData3.fileOperation = FileData::NewFile;
|
|
|
|
|
fileData3.binaryFiles = true;
|
|
|
|
|
|
|
|
|
|
QList<FileData> fileDataList8;
|
|
|
|
|
fileDataList8 << fileData1 << fileData2 << fileData3;
|
|
|
|
|
|
|
|
|
|
QTest::newRow("Binary files") << patch
|
|
|
|
|
<< fileDataList8;
|
|
|
|
|
|
2017-11-26 10:24:32 +02:00
|
|
|
//////////////
|
2017-12-06 21:30:57 +01:00
|
|
|
patch = "diff --git a/script.sh b/script.sh\n"
|
|
|
|
|
"old mode 100644\n"
|
|
|
|
|
"new mode 100755\n"
|
|
|
|
|
;
|
2017-11-26 10:24:32 +02:00
|
|
|
|
2022-09-27 15:13:33 +02:00
|
|
|
fileData1 = {};
|
2022-09-26 15:28:00 +02:00
|
|
|
fileData1.fileInfo = {DiffFileInfo("script.sh"), DiffFileInfo("script.sh")};
|
2017-11-26 10:24:32 +02:00
|
|
|
fileData1.fileOperation = FileData::ChangeMode;
|
|
|
|
|
|
|
|
|
|
QList<FileData> fileDataList9;
|
|
|
|
|
fileDataList9 << fileData1;
|
|
|
|
|
|
|
|
|
|
QTest::newRow("Mode change") << patch << fileDataList9;
|
|
|
|
|
|
2022-02-06 08:11:09 +02:00
|
|
|
//////////////
|
|
|
|
|
patch = R"(diff --git a/old.sh b/new.sh
|
|
|
|
|
old mode 100644
|
|
|
|
|
new mode 100755
|
|
|
|
|
similarity index 100%
|
|
|
|
|
rename from old.sh
|
|
|
|
|
rename to new.sh
|
|
|
|
|
)"
|
|
|
|
|
;
|
|
|
|
|
|
2022-09-27 15:13:33 +02:00
|
|
|
fileData1 = {};
|
2022-09-26 15:28:00 +02:00
|
|
|
fileData1.fileInfo = {DiffFileInfo("old.sh"), DiffFileInfo("new.sh")};
|
2022-02-06 08:11:09 +02:00
|
|
|
fileData1.fileOperation = FileData::RenameFile;
|
|
|
|
|
|
|
|
|
|
QList<FileData> fileDataList10;
|
|
|
|
|
fileDataList10 << fileData1;
|
|
|
|
|
|
|
|
|
|
QTest::newRow("Mode change + rename") << patch << fileDataList10;
|
|
|
|
|
|
2014-11-06 13:23:40 +01:00
|
|
|
//////////////
|
|
|
|
|
|
|
|
|
|
// Subversion New
|
2017-12-06 21:30:57 +01:00
|
|
|
patch = "Index: src/plugins/subversion/subversioneditor.cpp\n"
|
|
|
|
|
"===================================================================\n"
|
|
|
|
|
"--- src/plugins/subversion/subversioneditor.cpp\t(revision 0)\n"
|
|
|
|
|
"+++ src/plugins/subversion/subversioneditor.cpp\t(revision 0)\n"
|
|
|
|
|
"@@ -0,0 +125 @@\n\n";
|
2022-09-27 15:13:33 +02:00
|
|
|
fileData1 = {};
|
2022-09-26 15:28:00 +02:00
|
|
|
fileData1.fileInfo = {DiffFileInfo("src/plugins/subversion/subversioneditor.cpp"),
|
|
|
|
|
DiffFileInfo("src/plugins/subversion/subversioneditor.cpp")};
|
2022-09-27 15:13:33 +02:00
|
|
|
chunkData1 = {};
|
2022-09-26 14:15:40 +02:00
|
|
|
chunkData1.startingLineNumber = {-1, 124};
|
2014-11-06 13:23:40 +01:00
|
|
|
fileData1.chunks << chunkData1;
|
2017-11-26 10:24:32 +02:00
|
|
|
QList<FileData> fileDataList21;
|
|
|
|
|
fileDataList21 << fileData1;
|
2014-11-06 13:23:40 +01:00
|
|
|
QTest::newRow("Subversion New") << patch
|
2017-11-26 10:24:32 +02:00
|
|
|
<< fileDataList21;
|
2014-11-06 13:23:40 +01:00
|
|
|
|
|
|
|
|
//////////////
|
|
|
|
|
|
|
|
|
|
// Subversion Deleted
|
2017-12-06 21:30:57 +01:00
|
|
|
patch = "Index: src/plugins/subversion/subversioneditor.cpp\n"
|
|
|
|
|
"===================================================================\n"
|
|
|
|
|
"--- src/plugins/subversion/subversioneditor.cpp\t(revision 42)\n"
|
|
|
|
|
"+++ src/plugins/subversion/subversioneditor.cpp\t(working copy)\n"
|
|
|
|
|
"@@ -1,125 +0,0 @@\n\n";
|
2022-09-27 15:13:33 +02:00
|
|
|
fileData1 = {};
|
2022-09-26 15:28:00 +02:00
|
|
|
fileData1.fileInfo = {DiffFileInfo("src/plugins/subversion/subversioneditor.cpp"),
|
|
|
|
|
DiffFileInfo("src/plugins/subversion/subversioneditor.cpp")};
|
2022-09-27 15:13:33 +02:00
|
|
|
chunkData1 = {};
|
2022-09-26 14:15:40 +02:00
|
|
|
chunkData1.startingLineNumber = {0, -1};
|
2014-11-06 13:23:40 +01:00
|
|
|
fileData1.chunks << chunkData1;
|
2017-11-26 10:24:32 +02:00
|
|
|
QList<FileData> fileDataList22;
|
|
|
|
|
fileDataList22 << fileData1;
|
2014-11-06 13:23:40 +01:00
|
|
|
QTest::newRow("Subversion Deleted") << patch
|
2017-11-26 10:24:32 +02:00
|
|
|
<< fileDataList22;
|
2014-11-06 13:23:40 +01:00
|
|
|
|
|
|
|
|
//////////////
|
|
|
|
|
|
|
|
|
|
// Subversion Normal
|
2017-12-06 21:30:57 +01:00
|
|
|
patch = "Index: src/plugins/subversion/subversioneditor.cpp\n"
|
|
|
|
|
"===================================================================\n"
|
|
|
|
|
"--- src/plugins/subversion/subversioneditor.cpp\t(revision 42)\n"
|
|
|
|
|
"+++ src/plugins/subversion/subversioneditor.cpp\t(working copy)\n"
|
|
|
|
|
"@@ -120,7 +120,7 @@\n\n";
|
2022-09-27 15:13:33 +02:00
|
|
|
fileData1 = {};
|
2022-09-26 15:28:00 +02:00
|
|
|
fileData1.fileInfo = {DiffFileInfo("src/plugins/subversion/subversioneditor.cpp"),
|
|
|
|
|
DiffFileInfo("src/plugins/subversion/subversioneditor.cpp")};
|
2022-09-27 15:13:33 +02:00
|
|
|
chunkData1 = {};
|
2022-09-26 14:15:40 +02:00
|
|
|
chunkData1.startingLineNumber = {119, 119};
|
2014-11-06 13:23:40 +01:00
|
|
|
fileData1.chunks << chunkData1;
|
2017-11-26 10:24:32 +02:00
|
|
|
QList<FileData> fileDataList23;
|
|
|
|
|
fileDataList23 << fileData1;
|
2014-11-06 13:23:40 +01:00
|
|
|
QTest::newRow("Subversion Normal") << patch
|
2017-11-26 10:24:32 +02:00
|
|
|
<< fileDataList23;
|
2014-02-13 16:43:28 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void DiffEditor::Internal::DiffEditorPlugin::testReadPatch()
|
|
|
|
|
{
|
|
|
|
|
QFETCH(QString, sourcePatch);
|
|
|
|
|
QFETCH(QList<FileData>, fileDataList);
|
|
|
|
|
|
2023-02-11 23:21:58 +01:00
|
|
|
const std::optional<QList<FileData>> result = DiffUtils::readPatch(sourcePatch);
|
|
|
|
|
const bool ok = result.has_value();
|
2014-02-13 16:43:28 +01:00
|
|
|
|
|
|
|
|
QVERIFY(ok);
|
2023-02-11 23:21:58 +01:00
|
|
|
QCOMPARE(result->count(), fileDataList.count());
|
2014-02-13 16:43:28 +01:00
|
|
|
for (int i = 0; i < fileDataList.count(); i++) {
|
|
|
|
|
const FileData &origFileData = fileDataList.at(i);
|
2023-02-11 23:21:58 +01:00
|
|
|
const FileData &resultFileData = result->at(i);
|
2022-09-26 15:28:00 +02:00
|
|
|
QCOMPARE(resultFileData.fileInfo[LeftSide].fileName, origFileData.fileInfo[LeftSide].fileName);
|
|
|
|
|
QCOMPARE(resultFileData.fileInfo[LeftSide].typeInfo, origFileData.fileInfo[LeftSide].typeInfo);
|
|
|
|
|
QCOMPARE(resultFileData.fileInfo[RightSide].fileName, origFileData.fileInfo[RightSide].fileName);
|
|
|
|
|
QCOMPARE(resultFileData.fileInfo[RightSide].typeInfo, origFileData.fileInfo[RightSide].typeInfo);
|
2014-06-08 23:09:51 +03:00
|
|
|
QCOMPARE(resultFileData.chunks.count(), origFileData.chunks.count());
|
2014-07-07 14:26:41 +02:00
|
|
|
QCOMPARE(resultFileData.fileOperation, origFileData.fileOperation);
|
2014-02-13 16:43:28 +01:00
|
|
|
for (int j = 0; j < origFileData.chunks.count(); j++) {
|
|
|
|
|
const ChunkData &origChunkData = origFileData.chunks.at(j);
|
|
|
|
|
const ChunkData &resultChunkData = resultFileData.chunks.at(j);
|
2022-09-26 14:15:40 +02:00
|
|
|
QCOMPARE(resultChunkData.startingLineNumber[LeftSide], origChunkData.startingLineNumber[LeftSide]);
|
|
|
|
|
QCOMPARE(resultChunkData.startingLineNumber[RightSide], origChunkData.startingLineNumber[RightSide]);
|
2014-06-08 23:09:51 +03:00
|
|
|
QCOMPARE(resultChunkData.contextChunk, origChunkData.contextChunk);
|
|
|
|
|
QCOMPARE(resultChunkData.rows.count(), origChunkData.rows.count());
|
2014-02-13 16:43:28 +01:00
|
|
|
for (int k = 0; k < origChunkData.rows.count(); k++) {
|
|
|
|
|
const RowData &origRowData = origChunkData.rows.at(k);
|
|
|
|
|
const RowData &resultRowData = resultChunkData.rows.at(k);
|
2014-06-08 23:09:51 +03:00
|
|
|
QCOMPARE(resultRowData.equal, origRowData.equal);
|
2022-09-26 14:49:52 +02:00
|
|
|
QCOMPARE(resultRowData.line[LeftSide].text, origRowData.line[LeftSide].text);
|
|
|
|
|
QCOMPARE(resultRowData.line[LeftSide].textLineType, origRowData.line[LeftSide].textLineType);
|
|
|
|
|
QCOMPARE(resultRowData.line[RightSide].text, origRowData.line[RightSide].text);
|
|
|
|
|
QCOMPARE(resultRowData.line[RightSide].textLineType, origRowData.line[RightSide].textLineType);
|
2014-02-13 16:43:28 +01:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2019-11-20 16:01:17 +01:00
|
|
|
using ListOfStringPairs = QList<QPair<QString, QString>>;
|
|
|
|
|
|
2017-11-29 21:36:30 +01:00
|
|
|
void DiffEditor::Internal::DiffEditorPlugin::testFilterPatch_data()
|
|
|
|
|
{
|
|
|
|
|
QTest::addColumn<ChunkData>("chunk");
|
2019-11-20 16:01:17 +01:00
|
|
|
QTest::addColumn<ListOfStringPairs>("rows");
|
2017-11-29 21:36:30 +01:00
|
|
|
QTest::addColumn<ChunkSelection>("selection");
|
2022-09-29 15:31:27 +02:00
|
|
|
QTest::addColumn<PatchAction>("patchAction");
|
2017-11-29 21:36:30 +01:00
|
|
|
|
2022-09-27 15:13:33 +02:00
|
|
|
auto createChunk = [] {
|
2017-11-29 21:36:30 +01:00
|
|
|
ChunkData chunk;
|
|
|
|
|
chunk.contextInfo = "void DiffEditor::ctor()";
|
|
|
|
|
chunk.contextChunk = false;
|
2022-09-26 14:15:40 +02:00
|
|
|
chunk.startingLineNumber = {49, 49};
|
2017-11-29 21:36:30 +01:00
|
|
|
return chunk;
|
|
|
|
|
};
|
|
|
|
|
auto appendRow = [](ChunkData *chunk, const QString &left, const QString &right) {
|
|
|
|
|
RowData row;
|
|
|
|
|
row.equal = (left == right);
|
2022-09-26 14:49:52 +02:00
|
|
|
row.line[LeftSide].text = left;
|
|
|
|
|
row.line[LeftSide].textLineType = left.isEmpty() ? TextLineData::Separator : TextLineData::TextLine;
|
|
|
|
|
row.line[RightSide].text = right;
|
|
|
|
|
row.line[RightSide].textLineType = right.isEmpty() ? TextLineData::Separator : TextLineData::TextLine;
|
2017-11-29 21:36:30 +01:00
|
|
|
chunk->rows.append(row);
|
|
|
|
|
};
|
|
|
|
|
ChunkData chunk;
|
2019-11-20 16:01:17 +01:00
|
|
|
ListOfStringPairs rows;
|
2017-11-29 21:36:30 +01:00
|
|
|
|
|
|
|
|
chunk = createChunk();
|
|
|
|
|
appendRow(&chunk, "A", "A"); // 50
|
|
|
|
|
appendRow(&chunk, "", "B"); // 51 +
|
|
|
|
|
appendRow(&chunk, "C", "C"); // 52
|
2019-11-20 16:01:17 +01:00
|
|
|
rows = ListOfStringPairs {
|
|
|
|
|
{"A", "A"},
|
|
|
|
|
{"", "B"},
|
|
|
|
|
{"C", "C"}
|
2017-11-29 21:36:30 +01:00
|
|
|
};
|
2022-09-29 15:31:27 +02:00
|
|
|
QTest::newRow("one added") << chunk << rows << ChunkSelection() << PatchAction::Apply;
|
2017-11-29 21:36:30 +01:00
|
|
|
|
|
|
|
|
chunk = createChunk();
|
|
|
|
|
appendRow(&chunk, "A", "A"); // 50
|
|
|
|
|
appendRow(&chunk, "B", ""); // 51 -
|
|
|
|
|
appendRow(&chunk, "C", "C"); // 52
|
2019-11-20 16:01:17 +01:00
|
|
|
rows = ListOfStringPairs {
|
|
|
|
|
{"A", "A"},
|
|
|
|
|
{"B", ""},
|
|
|
|
|
{"C", "C"}
|
2017-11-29 21:36:30 +01:00
|
|
|
};
|
2022-09-29 15:31:27 +02:00
|
|
|
QTest::newRow("one removed") << chunk << rows << ChunkSelection() << PatchAction::Apply;
|
2017-11-29 21:36:30 +01:00
|
|
|
|
|
|
|
|
chunk = createChunk();
|
|
|
|
|
appendRow(&chunk, "A", "A"); // 50
|
|
|
|
|
appendRow(&chunk, "", "B"); // 51
|
|
|
|
|
appendRow(&chunk, "", "C"); // 52 +
|
|
|
|
|
appendRow(&chunk, "", "D"); // 53 +
|
|
|
|
|
appendRow(&chunk, "", "E"); // 54
|
|
|
|
|
appendRow(&chunk, "F", "F"); // 55
|
2019-11-20 16:01:17 +01:00
|
|
|
rows = ListOfStringPairs {
|
|
|
|
|
{"A", "A"},
|
|
|
|
|
{"", "C"},
|
|
|
|
|
{"", "D"},
|
|
|
|
|
{"F", "F"}
|
2017-11-29 21:36:30 +01:00
|
|
|
};
|
2022-09-29 15:31:27 +02:00
|
|
|
QTest::newRow("stage selected added") << chunk << rows << ChunkSelection({2, 3}, {2, 3})
|
|
|
|
|
<< PatchAction::Apply;
|
2017-11-29 21:36:30 +01:00
|
|
|
|
|
|
|
|
chunk = createChunk();
|
|
|
|
|
appendRow(&chunk, "A", "A"); // 50
|
|
|
|
|
appendRow(&chunk, "", "B"); // 51 +
|
|
|
|
|
appendRow(&chunk, "C", "D"); // 52
|
|
|
|
|
appendRow(&chunk, "E", "E"); // 53
|
2019-11-20 16:01:17 +01:00
|
|
|
rows = ListOfStringPairs {
|
|
|
|
|
{"A", "A"},
|
|
|
|
|
{"", "B"},
|
|
|
|
|
{"C", "C"},
|
|
|
|
|
{"E", "E"}
|
2017-11-29 21:36:30 +01:00
|
|
|
};
|
2022-09-29 15:31:27 +02:00
|
|
|
QTest::newRow("stage selected added keep changed") << chunk << rows << ChunkSelection({1}, {1})
|
|
|
|
|
<< PatchAction::Apply;
|
2017-11-29 21:36:30 +01:00
|
|
|
|
|
|
|
|
chunk = createChunk();
|
|
|
|
|
appendRow(&chunk, "A", "A"); // 50
|
|
|
|
|
appendRow(&chunk, "B", ""); // 51
|
|
|
|
|
appendRow(&chunk, "C", ""); // 52 -
|
|
|
|
|
appendRow(&chunk, "D", ""); // 53 -
|
|
|
|
|
appendRow(&chunk, "E", ""); // 54
|
|
|
|
|
appendRow(&chunk, "F", "F"); // 55
|
2019-11-20 16:01:17 +01:00
|
|
|
rows = ListOfStringPairs {
|
|
|
|
|
{"A", "A"},
|
|
|
|
|
{"B", "B"},
|
|
|
|
|
{"C", ""},
|
|
|
|
|
{"D", ""},
|
|
|
|
|
{"E", "E"},
|
|
|
|
|
{"F", "F"}
|
2017-11-29 21:36:30 +01:00
|
|
|
};
|
2022-09-29 15:31:27 +02:00
|
|
|
QTest::newRow("stage selected removed") << chunk << rows << ChunkSelection({2, 3}, {2, 3})
|
|
|
|
|
<< PatchAction::Apply;
|
2017-11-29 21:36:30 +01:00
|
|
|
|
|
|
|
|
chunk = createChunk();
|
|
|
|
|
appendRow(&chunk, "A", "A"); // 50
|
|
|
|
|
appendRow(&chunk, "B", ""); // 51
|
|
|
|
|
appendRow(&chunk, "C", ""); // 52 -
|
|
|
|
|
appendRow(&chunk, "", "D"); // 53 +
|
|
|
|
|
appendRow(&chunk, "", "E"); // 54
|
|
|
|
|
appendRow(&chunk, "F", "F"); // 55
|
2019-11-20 16:01:17 +01:00
|
|
|
rows = ListOfStringPairs {
|
|
|
|
|
{"A", "A"},
|
|
|
|
|
{"B", "B"},
|
|
|
|
|
{"C", ""},
|
|
|
|
|
{"", "D"},
|
|
|
|
|
{"F", "F"}
|
|
|
|
|
};
|
2022-09-29 15:31:27 +02:00
|
|
|
QTest::newRow("stage selected added/removed") << chunk << rows << ChunkSelection({2, 3}, {2, 3})
|
|
|
|
|
<< PatchAction::Apply;
|
2019-11-20 16:01:17 +01:00
|
|
|
|
|
|
|
|
chunk = createChunk();
|
|
|
|
|
appendRow(&chunk, "A", "A"); // 50
|
|
|
|
|
appendRow(&chunk, "B", "C"); // 51 -/+
|
|
|
|
|
appendRow(&chunk, "D", "D"); // 52
|
|
|
|
|
rows = ListOfStringPairs {
|
|
|
|
|
{"A", "A"},
|
|
|
|
|
{"B", "C"},
|
|
|
|
|
{"D", "D"}
|
|
|
|
|
};
|
2022-09-29 15:31:27 +02:00
|
|
|
QTest::newRow("stage modified row") << chunk << rows << ChunkSelection({1}, {1})
|
|
|
|
|
<< PatchAction::Apply;
|
2019-11-20 16:01:17 +01:00
|
|
|
|
|
|
|
|
chunk = createChunk();
|
|
|
|
|
appendRow(&chunk, "A", "A"); // 50
|
|
|
|
|
appendRow(&chunk, "B", "C"); // 51 -/+
|
|
|
|
|
appendRow(&chunk, "D", "D"); // 52
|
|
|
|
|
rows = ListOfStringPairs {
|
|
|
|
|
{"A", "A"},
|
|
|
|
|
{"B", "C"},
|
|
|
|
|
{"D", "D"}
|
|
|
|
|
};
|
2022-09-29 15:31:27 +02:00
|
|
|
QTest::newRow("stage modified and unmodified rows") << chunk << rows
|
|
|
|
|
<< ChunkSelection({0, 1, 2}, {0, 1, 2}) << PatchAction::Apply;
|
2019-11-20 16:01:17 +01:00
|
|
|
|
|
|
|
|
chunk = createChunk();
|
|
|
|
|
appendRow(&chunk, "A", "A"); // 50
|
|
|
|
|
appendRow(&chunk, "B", "C"); // 51 -/+
|
|
|
|
|
appendRow(&chunk, "D", "D"); // 52
|
|
|
|
|
rows = ListOfStringPairs {
|
|
|
|
|
{"A", "A"},
|
|
|
|
|
{"B", "C"},
|
|
|
|
|
{"D", "D"}
|
|
|
|
|
};
|
2022-09-29 15:31:27 +02:00
|
|
|
QTest::newRow("stage unmodified left rows") << chunk << rows << ChunkSelection({0, 1, 2}, {1})
|
|
|
|
|
<< PatchAction::Apply;
|
2019-11-20 16:01:17 +01:00
|
|
|
|
|
|
|
|
chunk = createChunk();
|
|
|
|
|
appendRow(&chunk, "A", "A"); // 50
|
|
|
|
|
appendRow(&chunk, "B", "C"); // 51 -/+
|
|
|
|
|
appendRow(&chunk, "D", "D"); // 52
|
|
|
|
|
rows = ListOfStringPairs {
|
|
|
|
|
{"A", "A"},
|
|
|
|
|
{"B", "C"},
|
|
|
|
|
{"D", "D"}
|
2017-11-29 21:36:30 +01:00
|
|
|
};
|
2022-09-29 15:31:27 +02:00
|
|
|
QTest::newRow("stage unmodified right rows") << chunk << rows << ChunkSelection({1}, {0, 1, 2})
|
|
|
|
|
<< PatchAction::Apply;
|
2017-11-29 21:36:30 +01:00
|
|
|
|
|
|
|
|
chunk = createChunk();
|
|
|
|
|
appendRow(&chunk, "A", "A"); // 50
|
|
|
|
|
appendRow(&chunk, "B", "C"); // 51 -/+
|
|
|
|
|
appendRow(&chunk, "D", "D"); // 52
|
2019-11-20 16:01:17 +01:00
|
|
|
rows = ListOfStringPairs {
|
|
|
|
|
{"A", "A"},
|
|
|
|
|
{"B", ""},
|
|
|
|
|
{"D", "D"}
|
2017-11-29 21:36:30 +01:00
|
|
|
};
|
2022-09-29 15:31:27 +02:00
|
|
|
QTest::newRow("stage left only") << chunk << rows << ChunkSelection({1}, {})
|
|
|
|
|
<< PatchAction::Apply;
|
2019-11-20 16:01:17 +01:00
|
|
|
|
|
|
|
|
chunk = createChunk();
|
|
|
|
|
appendRow(&chunk, "A", "A"); // 50
|
|
|
|
|
appendRow(&chunk, "B", "C"); // 51 -/+
|
|
|
|
|
appendRow(&chunk, "D", "D"); // 52
|
|
|
|
|
rows = ListOfStringPairs {
|
|
|
|
|
{"A", "A"},
|
|
|
|
|
{"B", "B"},
|
|
|
|
|
{"", "C"},
|
|
|
|
|
{"D", "D"}
|
|
|
|
|
};
|
2022-09-29 15:31:27 +02:00
|
|
|
QTest::newRow("stage right only") << chunk << rows << ChunkSelection({}, {1})
|
|
|
|
|
<< PatchAction::Apply;
|
2019-11-20 16:01:17 +01:00
|
|
|
|
|
|
|
|
chunk = createChunk();
|
|
|
|
|
appendRow(&chunk, "A", "A"); // 50
|
|
|
|
|
appendRow(&chunk, "B", "C"); // 51 -/+
|
|
|
|
|
appendRow(&chunk, "D", "D"); // 52
|
|
|
|
|
rows = ListOfStringPairs {
|
|
|
|
|
{"A", "A"},
|
|
|
|
|
{"B", "C"},
|
|
|
|
|
{"D", "D"}
|
|
|
|
|
};
|
2022-09-29 15:31:27 +02:00
|
|
|
QTest::newRow("stage modified row and revert") << chunk << rows << ChunkSelection({1}, {1})
|
|
|
|
|
<< PatchAction::Revert;
|
2019-11-20 16:01:17 +01:00
|
|
|
|
|
|
|
|
chunk = createChunk();
|
|
|
|
|
appendRow(&chunk, "A", "A"); // 50
|
|
|
|
|
appendRow(&chunk, "B", "C"); // 51 -/+
|
|
|
|
|
appendRow(&chunk, "D", "D"); // 52
|
|
|
|
|
rows = ListOfStringPairs {
|
|
|
|
|
{"A", "A"},
|
|
|
|
|
{"B", ""},
|
|
|
|
|
{"C", "C"},
|
|
|
|
|
{"D", "D"}
|
|
|
|
|
};
|
|
|
|
|
// symmetric to: "stage right only"
|
2022-09-29 15:31:27 +02:00
|
|
|
QTest::newRow("stage left only and revert") << chunk << rows << ChunkSelection({1}, {})
|
|
|
|
|
<< PatchAction::Revert;
|
2019-11-20 16:01:17 +01:00
|
|
|
|
|
|
|
|
chunk = createChunk();
|
|
|
|
|
appendRow(&chunk, "A", "A"); // 50
|
|
|
|
|
appendRow(&chunk, "B", "C"); // 51 -/+
|
|
|
|
|
appendRow(&chunk, "D", "D"); // 52
|
|
|
|
|
rows = ListOfStringPairs {
|
|
|
|
|
{"A", "A"},
|
|
|
|
|
{"", "C"},
|
|
|
|
|
{"D", "D"}
|
|
|
|
|
};
|
|
|
|
|
// symmetric to: "stage left only"
|
2022-09-29 15:31:27 +02:00
|
|
|
QTest::newRow("stage right only and revert") << chunk << rows << ChunkSelection({}, {1})
|
|
|
|
|
<< PatchAction::Revert;
|
2017-11-29 21:36:30 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void DiffEditor::Internal::DiffEditorPlugin::testFilterPatch()
|
|
|
|
|
{
|
|
|
|
|
QFETCH(ChunkData, chunk);
|
2019-11-20 16:01:17 +01:00
|
|
|
QFETCH(ListOfStringPairs, rows);
|
2017-11-29 21:36:30 +01:00
|
|
|
QFETCH(ChunkSelection, selection);
|
2022-09-29 15:31:27 +02:00
|
|
|
QFETCH(PatchAction, patchAction);
|
2017-11-29 21:36:30 +01:00
|
|
|
|
2022-09-29 15:31:27 +02:00
|
|
|
const ChunkData result = DiffEditorDocument::filterChunk(chunk, selection, patchAction);
|
2019-11-20 16:01:17 +01:00
|
|
|
QCOMPARE(result.rows.size(), rows.size());
|
|
|
|
|
for (int i = 0; i < rows.size(); ++i) {
|
2022-09-26 14:49:52 +02:00
|
|
|
QCOMPARE(result.rows.at(i).line[LeftSide].text, rows.at(i).first);
|
|
|
|
|
QCOMPARE(result.rows.at(i).line[RightSide].text, rows.at(i).second);
|
2017-11-29 21:36:30 +01:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2014-02-13 16:43:28 +01:00
|
|
|
#endif // WITH_TESTS
|
|
|
|
|
|
|
|
|
|
#include "diffeditorplugin.moc"
|