feat(playlist): compact rows with clean titles and durations
This commit is contained in:
1 parent
b34a01a92f
commit
76ba7b0be0
9 files changed
+370
-55
No files matched your search
@@ -16,7 +16,7 @@ target_include_directories(glossarystoretest PRIVATE ../src/translate)
|
||||
|
||||
ecm_add_test(playlistmodeltest.cpp ../src/playlist/playlistmodel.cpp
|
||||
TEST_NAME playlistmodeltest
|
||||
LINK_LIBRARIES Qt6::Qml Qt6::Test
|
||||
LINK_LIBRARIES qtpotato_core Qt6::Qml Qt6::Concurrent Qt6::Test
|
||||
)
|
||||
target_include_directories(playlistmodeltest PRIVATE ../src/playlist)
|
||||
|
||||
@@ -24,3 +24,8 @@ ecm_add_test(trackselectiontest.cpp
|
||||
TEST_NAME trackselectiontest
|
||||
LINK_LIBRARIES qtpotato_core Qt6::Test
|
||||
)
|
||||
|
||||
ecm_add_test(mediainfotest.cpp
|
||||
TEST_NAME mediainfotest
|
||||
LINK_LIBRARIES qtpotato_core Qt6::Test
|
||||
)
|
||||
@@ -0,0 +1,64 @@
|
||||
// SPDX-FileCopyrightText: 2026 Tri Vo Khac
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
#include "mediainfo.h"
|
||||
|
||||
#include <QProcess>
|
||||
#include <QStandardPaths>
|
||||
#include <QTemporaryDir>
|
||||
#include <QTest>
|
||||
|
||||
using namespace Qt::Literals::StringLiterals;
|
||||
|
||||
class MediaInfoTest : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
private Q_SLOTS:
|
||||
void cleanTitle_data()
|
||||
{
|
||||
QTest::addColumn<QString>("fileName");
|
||||
QTest::addColumn<QString>("title");
|
||||
|
||||
QTest::newRow("scene episode") << u"VisionQuest.S01E01.No.Strings.DSNP.DV.HDR.WEB-DL.DDP5.1.Atmos.H.265-GRP.mkv"_s
|
||||
<< u"S01E01 · No Strings"_s;
|
||||
QTest::newRow("episode without title") << u"The.Show.S02E10.1080p.WEB.h264-GRP.mkv"_s << u"The Show · S02E10"_s;
|
||||
QTest::newRow("lowercase double episode") << u"show.s01e01e02.pilot.720p.hdtv.mkv"_s << u"S01E01E02 · pilot"_s;
|
||||
QTest::newRow("spaced episode") << u"Mr. Robot - S01E01 - eps1.0_hellofriend.mov.mkv"_s << u"S01E01 · eps1.0 hellofriend.mov"_s;
|
||||
QTest::newRow("movie with year") << u"Dune.Part.Two.2024.2160p.UHD.BluRay.x265-GRP.mkv"_s << u"Dune Part Two (2024)"_s;
|
||||
QTest::newRow("anime release") << u"[SubsPlease] Frieren - 05 (1080p) [A1B2C3D4].mkv"_s << u"Frieren - 05"_s;
|
||||
QTest::newRow("plain name") << u"Holiday 2019 at the beach.mp4"_s << u"Holiday 2019 at the beach"_s;
|
||||
QTest::newRow("music") << u"01 - Intro.flac"_s << u"01 - Intro"_s;
|
||||
QTest::newRow("only tags") << u"1080p.mkv"_s << u"1080p"_s;
|
||||
}
|
||||
|
||||
void cleanTitle()
|
||||
{
|
||||
QFETCH(QString, fileName);
|
||||
QFETCH(QString, title);
|
||||
QCOMPARE(MediaInfo::cleanTitle(fileName), title);
|
||||
}
|
||||
|
||||
void probeDurationReadsTheLength()
|
||||
{
|
||||
const QString ffmpeg = QStandardPaths::findExecutable(u"ffmpeg"_s);
|
||||
if (ffmpeg.isEmpty()) {
|
||||
QSKIP("ffmpeg is needed to make a sample file");
|
||||
}
|
||||
QTemporaryDir dir;
|
||||
const QString path = dir.filePath(u"tone.mka"_s);
|
||||
QProcess process;
|
||||
process.start(ffmpeg, {u"-v"_s, u"error"_s, u"-f"_s, u"lavfi"_s, u"-i"_s, u"sine=duration=3"_s, path});
|
||||
QVERIFY(process.waitForFinished());
|
||||
QCOMPARE(process.exitCode(), 0);
|
||||
|
||||
const std::optional<double> seconds = MediaInfo::probeDuration(path);
|
||||
QVERIFY(seconds);
|
||||
QVERIFY2(qAbs(*seconds - 3) < 0.1, qPrintable(QString::number(*seconds)));
|
||||
QVERIFY(!MediaInfo::probeDuration(dir.filePath(u"missing.mkv"_s)));
|
||||
}
|
||||
};
|
||||
|
||||
QTEST_GUILESS_MAIN(MediaInfoTest)
|
||||
|
||||
#include "mediainfotest.moc"
|
||||
@@ -4,7 +4,9 @@
|
||||
#include "playlistmodel.h"
|
||||
|
||||
#include <QFile>
|
||||
#include <QProcess>
|
||||
#include <QSignalSpy>
|
||||
#include <QStandardPaths>
|
||||
#include <QTemporaryDir>
|
||||
#include <QTest>
|
||||
|
||||
@@ -98,6 +100,31 @@ private Q_SLOTS:
|
||||
QCOMPARE(model.playingIndex(), -1);
|
||||
QCOMPARE(model.count(), 1);
|
||||
}
|
||||
|
||||
void titleAndDurationRoles()
|
||||
{
|
||||
const QString ffmpeg = QStandardPaths::findExecutable(u"ffmpeg"_s);
|
||||
if (ffmpeg.isEmpty()) {
|
||||
QSKIP("ffmpeg is needed to make a sample file");
|
||||
}
|
||||
QTemporaryDir dir;
|
||||
const QString path = dir.filePath(u"Show.S01E02.The.Tone.1080p.WEB.mka"_s);
|
||||
QProcess process;
|
||||
process.start(ffmpeg, {u"-v"_s, u"error"_s, u"-f"_s, u"lavfi"_s, u"-i"_s, u"sine=duration=2"_s, path});
|
||||
QVERIFY(process.waitForFinished());
|
||||
QCOMPARE(process.exitCode(), 0);
|
||||
|
||||
PlaylistModel model;
|
||||
QSignalSpy changed(&model, &QAbstractItemModel::dataChanged);
|
||||
model.append({QUrl::fromLocalFile(path), QUrl(u"https://example.com/a"_s)});
|
||||
QCOMPARE(model.data(model.index(0), PlaylistModel::TitleRole).toString(), u"S01E02 · The Tone"_s);
|
||||
QCOMPARE(model.data(model.index(1), PlaylistModel::TitleRole).toString(), u"https://example.com/a"_s);
|
||||
QCOMPARE(model.data(model.index(1), PlaylistModel::DurationRole).toDouble(), -1.0);
|
||||
|
||||
QTRY_COMPARE(changed.count(), 1);
|
||||
QCOMPARE(changed.first().at(2).value<QList<int>>(), QList<int>{PlaylistModel::DurationRole});
|
||||
QVERIFY(qAbs(model.data(model.index(0), PlaylistModel::DurationRole).toDouble() - 2) < 0.1);
|
||||
}
|
||||
};
|
||||
|
||||
QTEST_GUILESS_MAIN(PlaylistModelTest)
|
||||
|
||||
Reference in new issue
Block a user