-
-
Notifications
You must be signed in to change notification settings - Fork 1.3k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #3741 from uklotzde/fileinfo
Add mixxx::FileInfo for file system references
- Loading branch information
Showing
6 changed files
with
430 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,101 @@ | ||
#include "util/fileinfo.h" | ||
|
||
#include <gtest/gtest.h> | ||
|
||
#include <QTemporaryDir> | ||
#include <QtDebug> | ||
|
||
namespace mixxx { | ||
|
||
class FileInfoTest : public testing::Test { | ||
protected: | ||
const QTemporaryDir m_tempDir; | ||
|
||
const QString m_relativePath; | ||
const QString m_absolutePath; | ||
|
||
const QString m_relativePathMissing; | ||
const QString m_absolutePathMissing; | ||
|
||
FileInfoTest() | ||
: m_relativePath(QStringLiteral("relative")), | ||
m_absolutePath(m_tempDir.filePath(m_relativePath)), | ||
m_relativePathMissing(QStringLiteral("missing")), | ||
m_absolutePathMissing(m_tempDir.filePath(m_relativePathMissing)) { | ||
} | ||
|
||
void SetUp() override { | ||
ASSERT_TRUE(m_tempDir.isValid()); | ||
ASSERT_TRUE(QDir(m_tempDir.path()).mkpath(m_relativePath)); | ||
ASSERT_TRUE(FileInfo(m_absolutePath).exists()); | ||
ASSERT_FALSE(FileInfo(m_absolutePathMissing).exists()); | ||
} | ||
}; | ||
|
||
TEST_F(FileInfoTest, emptyPathIsRelative) { | ||
EXPECT_FALSE(FileInfo().isAbsolute()); | ||
EXPECT_TRUE(FileInfo().isRelative()); | ||
} | ||
|
||
TEST_F(FileInfoTest, nonEmptyPathIsEitherAbsoluteOrRelative) { | ||
EXPECT_TRUE(FileInfo(m_absolutePath).isAbsolute()); | ||
EXPECT_FALSE(FileInfo(m_absolutePath).isRelative()); | ||
EXPECT_TRUE(FileInfo(m_absolutePathMissing).isAbsolute()); | ||
EXPECT_FALSE(FileInfo(m_absolutePathMissing).isRelative()); | ||
EXPECT_FALSE(FileInfo(m_relativePath).isAbsolute()); | ||
EXPECT_TRUE(FileInfo(m_relativePath).isRelative()); | ||
EXPECT_FALSE(FileInfo(m_relativePathMissing).isAbsolute()); | ||
EXPECT_TRUE(FileInfo(m_relativePathMissing).isRelative()); | ||
} | ||
|
||
TEST_F(FileInfoTest, hasLocation) { | ||
EXPECT_FALSE(FileInfo().hasLocation()); | ||
EXPECT_TRUE(FileInfo(m_absolutePath).hasLocation()); | ||
EXPECT_TRUE(FileInfo(m_absolutePath).hasLocation()); | ||
EXPECT_FALSE(FileInfo(m_relativePath).hasLocation()); | ||
EXPECT_TRUE(FileInfo(m_absolutePathMissing).hasLocation()); | ||
EXPECT_FALSE(FileInfo(m_relativePathMissing).hasLocation()); | ||
} | ||
|
||
TEST_F(FileInfoTest, freshCanonicalFileInfo) { | ||
FileInfo fileInfo(m_absolutePathMissing); | ||
// This test assumes that caching is enabled resulting | ||
// in expected inconsistencies until refreshed. | ||
ASSERT_TRUE(fileInfo.m_fileInfo.caching()); | ||
|
||
ASSERT_TRUE(fileInfo.canonicalLocation().isEmpty()); | ||
ASSERT_TRUE(fileInfo.resolveCanonicalLocation().isEmpty()); | ||
|
||
// Restore the missing file | ||
QFile file(m_absolutePathMissing); | ||
ASSERT_FALSE(fileInfo.checkFileExists()); | ||
ASSERT_TRUE(file.open(QIODevice::ReadWrite | QIODevice::NewOnly)); | ||
ASSERT_TRUE(fileInfo.checkFileExists()); | ||
|
||
// The cached canonical location should still be invalid | ||
EXPECT_TRUE(fileInfo.canonicalLocation().isEmpty()); | ||
// The refreshed canonical location should be valid | ||
EXPECT_FALSE(fileInfo.resolveCanonicalLocation().isEmpty()); | ||
// The cached canonical location should have been updated | ||
EXPECT_FALSE(fileInfo.canonicalLocation().isEmpty()); | ||
|
||
// Remove the file | ||
ASSERT_TRUE(file.remove()); | ||
ASSERT_FALSE(fileInfo.checkFileExists()); | ||
ASSERT_TRUE(FileInfo(m_absolutePathMissing).canonicalLocation().isEmpty()); | ||
|
||
// Note: Qt (5.14.x) doesn't seem to invalidate the canonical location | ||
// after it has been set once, even when refreshing the QFileInfo. This | ||
// is what the remaining part of the test validates, although Mixxx does | ||
// NOT rely on this behavior! Just to get notified when this behavior | ||
// changes for some future Qt version and for ensuring that the behavior | ||
// is identical on all platforms. | ||
|
||
// The cached canonical location should still be valid | ||
EXPECT_FALSE(fileInfo.canonicalLocation().isEmpty()); | ||
// The canonical location should not be refreshed again, i.e. it remains | ||
// valid after the file has disappeared | ||
EXPECT_FALSE(fileInfo.resolveCanonicalLocation().isEmpty()); | ||
} | ||
|
||
} // namespace mixxx |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
#include "util/fileinfo.h" | ||
|
||
namespace mixxx { | ||
|
||
// static | ||
bool FileInfo::isRootSubCanonicalLocation( | ||
const QString& rootCanonicalLocation, | ||
const QString& subCanonicalLocation) { | ||
VERIFY_OR_DEBUG_ASSERT(!rootCanonicalLocation.isEmpty()) { | ||
return false; | ||
} | ||
VERIFY_OR_DEBUG_ASSERT(!subCanonicalLocation.isEmpty()) { | ||
return false; | ||
} | ||
DEBUG_ASSERT(QDir::isAbsolutePath(rootCanonicalLocation)); | ||
DEBUG_ASSERT(QDir::isAbsolutePath(subCanonicalLocation)); | ||
if (subCanonicalLocation.size() < rootCanonicalLocation.size()) { | ||
return false; | ||
} | ||
if (subCanonicalLocation.size() > rootCanonicalLocation.size() && | ||
subCanonicalLocation[rootCanonicalLocation.size()] != QChar('/')) { | ||
return false; | ||
} | ||
return subCanonicalLocation.startsWith(rootCanonicalLocation); | ||
} | ||
|
||
QString FileInfo::resolveCanonicalLocation() { | ||
// Note: We return here the cached value, that was calculated just after | ||
// init this FileInfo object. This will avoid repeated use of the time | ||
// consuming file I/O. | ||
QString currentCanonicalLocation = canonicalLocation(); | ||
if (!currentCanonicalLocation.isEmpty()) { | ||
return currentCanonicalLocation; | ||
} | ||
m_fileInfo.refresh(); | ||
// Return whatever is available after the refresh | ||
return canonicalLocation(); | ||
} | ||
|
||
} // namespace mixxx |
Oops, something went wrong.