Loading files
/*
* LibrePCB - Professional EDA for everyone!
* Copyright (C) 2013 LibrePCB Developers, see AUTHORS.md for contributors.
* https://librepcb.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 3 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, see <http://www.gnu.org/licenses/>.
*/
/*******************************************************************************
* Includes
******************************************************************************/
#include <gtest/gtest.h>
#include <librepcb/core/fileio/asynccopyoperation.h>
#include <librepcb/core/fileio/fileutils.h>
#include <QtCore>
/*******************************************************************************
* Namespace
******************************************************************************/
namespace librepcb {
namespace tests {
/*******************************************************************************
* Test Class
******************************************************************************/
class AsyncCopyOperationTest : public ::testing::Test {
public:
FilePath mTmpDir;
FilePath mNonExistingDir;
FilePath mEmptyDir;
FilePath mPopulatedDir;
FilePath mDestinationDir;
int mSignalStarted;
QStringList mSignalProgressStatus;
QList<int> mSignalProgressPercent;
int mSignalSucceeded;
QStringList mSignalFailed;
int mSignalFinished;
QObject mContext;
AsyncCopyOperationTest()
: mTmpDir(FilePath::getRandomTempPath()),
mNonExistingDir(mTmpDir.getPathTo("non existing")),
mEmptyDir(mTmpDir.getPathTo("empty directory")),
mPopulatedDir(mTmpDir.getPathTo("populated directory")),
mDestinationDir(mTmpDir.getPathTo("destination directory")),
mSignalStarted(0),
mSignalProgressStatus(),
mSignalProgressPercent(),
mSignalSucceeded(0),
mSignalFailed(),
mSignalFinished(0),
mContext() {
FileUtils::makePath(mEmptyDir);
FileUtils::writeFile(mPopulatedDir.getPathTo("foo/a dir/f"), "A");
FileUtils::writeFile(mPopulatedDir.getPathTo(".dotfile"), "B");
}
~AsyncCopyOperationTest() override {
QDir(mTmpDir.toStr()).removeRecursively();
}
bool run(AsyncCopyOperation& copy, unsigned long timeout) {
// Connect all signals by hand because QSignalSpy is not threadsafe!
QObject::connect(
©, &AsyncCopyOperation::startedCopy, &mContext,
[this]() { ++mSignalStarted; }, Qt::QueuedConnection);
QObject::connect(
©, &AsyncCopyOperation::progressStatus, &mContext,
[this](const QString& status) {
std::cout << "STATUS: " << status.toStdString() << std::endl;
mSignalProgressStatus.append(status);
},
Qt::QueuedConnection);
QObject::connect(
©, &AsyncCopyOperation::progressPercent, &mContext,
[this](int percent) {
std::cout << "PROGRESS: " << percent << std::endl;
mSignalProgressPercent.append(percent);
},
Qt::QueuedConnection);
QObject::connect(
©, &AsyncCopyOperation::succeeded, &mContext,
[this]() { ++mSignalSucceeded; }, Qt::QueuedConnection);
QObject::connect(
©, &AsyncCopyOperation::failed, &mContext,
[this](const QString& error) {
std::cout << "ERROR: " << error.toStdString() << std::endl;
mSignalFailed.append(error);
},
Qt::QueuedConnection);
QObject::connect(
©, &AsyncCopyOperation::finishedCopy, &mContext,
[this]() { ++mSignalFinished; }, Qt::QueuedConnection);
copy.start();
const bool success = copy.wait(timeout);
// Enforce processing the emitted signals. Needs to be called twice, see
// https://github.com/LibrePCB/LibrePCB/issues/1061.
qApp->processEvents();
qApp->processEvents();
return success;
}
};
/*******************************************************************************
* Test Methods
******************************************************************************/
TEST_F(AsyncCopyOperationTest, testEmptySourceDir) {
// Perform copy operation.
AsyncCopyOperation copy(mEmptyDir, mDestinationDir);
EXPECT_TRUE(run(copy, 5000));
// Verify emitted signals.
EXPECT_EQ(mSignalStarted, 1);
EXPECT_GE(mSignalProgressStatus.count(), 1);
EXPECT_GE(mSignalProgressPercent.count(), 1);
EXPECT_EQ(mSignalSucceeded, 1);
EXPECT_EQ(mSignalFailed.count(), 0);
EXPECT_EQ(mSignalFinished, 1);
// Verify copied directory.
EXPECT_TRUE(mDestinationDir.isEmptyDir());
}
TEST_F(AsyncCopyOperationTest, testPopulatedSourceDir) {
// Perform copy operation.
AsyncCopyOperation copy(mPopulatedDir, mDestinationDir);
EXPECT_TRUE(run(copy, 5000));
// Verify emitted signals.
EXPECT_EQ(mSignalStarted, 1);
EXPECT_GE(mSignalProgressStatus.count(), 1);
EXPECT_GE(mSignalProgressPercent.count(), 1);
EXPECT_EQ(mSignalSucceeded, 1);
EXPECT_EQ(mSignalFailed.count(), 0);
EXPECT_EQ(mSignalFinished, 1);
// Verify copied directory.
EXPECT_EQ(FileUtils::readFile(mDestinationDir.getPathTo("foo/a dir/f")), "A");
EXPECT_EQ(FileUtils::readFile(mDestinationDir.getPathTo(".dotfile")), "B");
}
TEST_F(AsyncCopyOperationTest, testNonExistentSourceDir) {
// Perform copy operation.
AsyncCopyOperation copy(mNonExistingDir, mDestinationDir);
EXPECT_TRUE(run(copy, 5000));
// Verify emitted signals.
EXPECT_EQ(mSignalStarted, 1);
EXPECT_GE(mSignalProgressStatus.count(), 1);
EXPECT_GE(mSignalProgressPercent.count(), 0);
EXPECT_EQ(mSignalSucceeded, 0);
EXPECT_EQ(mSignalFailed.count(), 1);
EXPECT_EQ(mSignalFinished, 1);
// Verify copied directory.
EXPECT_FALSE(mDestinationDir.isExistingDir());
}
TEST_F(AsyncCopyOperationTest, testExistingDestinationDir) {
// Perform copy operation.
AsyncCopyOperation copy(mEmptyDir, mPopulatedDir);
EXPECT_TRUE(run(copy, 5000));
// Verify emitted signals.
EXPECT_EQ(mSignalStarted, 1);
EXPECT_GE(mSignalProgressStatus.count(), 1);
EXPECT_GE(mSignalProgressPercent.count(), 0);
EXPECT_EQ(mSignalSucceeded, 0);
EXPECT_EQ(mSignalFailed.count(), 1);
EXPECT_EQ(mSignalFinished, 1);
// Verify that the already existing destination is not removed.
EXPECT_TRUE(mPopulatedDir.getPathTo("foo/a dir/f").isExistingFile());
EXPECT_TRUE(mPopulatedDir.getPathTo(".dotfile").isExistingFile());
}
/*******************************************************************************
* End of File
******************************************************************************/
} // namespace tests
} // namespace librepcb
c730ec352This file is pinned to the selected release. Download the original to open it in your design tool.