Commit 4e1db7e6 authored by Jean-Baptiste Mardelle's avatar Jean-Baptiste Mardelle
Browse files

Fix major corruption on undo/redo clip cut, with tests

parent 424ab7bb
Pipeline #181360 failed with stage
in 3 minutes and 13 seconds
......@@ -1162,8 +1162,10 @@ void ClipModel::setCurrentTrackId(int tid, bool finalMove)
}
}
if (finalMove && tid != -1 && m_lastTrackId != m_currentTrackId) {
refreshProducerFromBin(m_currentTrackId);
if (finalMove && m_lastTrackId != m_currentTrackId) {
if (tid != -1) {
refreshProducerFromBin(m_currentTrackId);
}
m_lastTrackId = m_currentTrackId;
}
}
......
......@@ -19,6 +19,7 @@ add_executable(runTests
treetest.cpp
trimmingtest.cpp
cachetest.cpp
movetest.cpp
)
set_property(TARGET runTests PROPERTY CXX_STANDARD 14)
target_link_libraries(runTests kdenliveLib)
......
#include "test_utils.hpp"
using namespace fakeit;
Mlt::Profile profile_move;
TEST_CASE("Cut undo/redo", "[MoveClips]")
{
// Create timeline
auto binModel = pCore->projectItemModel();
binModel->clean();
std::shared_ptr<DocUndoStack> undoStack = std::make_shared<DocUndoStack>(nullptr);
std::shared_ptr<MarkerListModel> guideModel = std::make_shared<MarkerListModel>(undoStack);
// Here we do some trickery to enable testing.
// We mock the project class so that the undoStack function returns our undoStack
Mock<ProjectManager> pmMock;
When(Method(pmMock, undoStack)).AlwaysReturn(undoStack);
When(Method(pmMock, cacheDir)).AlwaysReturn(QDir(QStandardPaths::writableLocation(QStandardPaths::CacheLocation)));
ProjectManager &mocked = pmMock.get();
pCore->m_projectManager = &mocked;
// We also mock timeline object to spy few functions and mock others
TimelineItemModel tim(&profile_move, undoStack);
Mock<TimelineItemModel> timMock(tim);
auto timeline = std::shared_ptr<TimelineItemModel>(&timMock.get(), [](...) {});
TimelineItemModel::finishConstruct(timeline, guideModel);
// Create a request
int tid1 = TrackModel::construct(timeline, -1, -1, QString(), true);
int tid3 = TrackModel::construct(timeline, -1, -1, QString(), true);
int tid2 = TrackModel::construct(timeline);
int tid4 = TrackModel::construct(timeline);
// Create clip with audio (40 frames long)
QString binId = createAVProducer(profile_move, binModel);
// Setup insert stream data
QMap <int, QString>audioInfo;
audioInfo.insert(1,QStringLiteral("stream1"));
timeline->m_binAudioTargets = audioInfo;
// Create AV clip 1
int cid1;
int cid2;
int cid3;
int cid4;
int cid5;
REQUIRE(timeline->requestClipInsertion(binId, tid2, 100, cid1));
cid2 = timeline->getClipSplitPartner(cid1);
SECTION("Ensure all clip instances on a track use the same producer")
{
REQUIRE(timeline->getItemTrackId(cid2) == tid3);
REQUIRE(timeline->getItemTrackId(cid1) == tid2);
Mlt::Producer prod1 = *(timeline->getClipPtr(cid1));
Mlt::Producer prod2 = *(timeline->getClipPtr(cid2));
// Clips on different tracks shoud not use the same producer
REQUIRE(!prod1.same_clip(prod2));
// Split clip
REQUIRE(TimelineFunctions::requestClipCut(timeline, cid1, 110));
cid3 = timeline->getClipByPosition(tid2, 111);
cid4 = timeline->getClipSplitPartner(cid3);
REQUIRE(timeline->getItemTrackId(cid4) == tid3);
REQUIRE(timeline->getItemTrackId(cid3) == tid2);
Mlt::Producer prod3 = *(timeline->getClipPtr(cid3));
Mlt::Producer prod4 = *(timeline->getClipPtr(cid4));
// Clips on different tracks shoud not use the same producer
REQUIRE(!prod3.same_clip(prod4));
// Clips on same track shoud use the same producer
REQUIRE(prod1.same_clip(prod3));
REQUIRE(prod2.same_clip(prod4));
// Undo and redo cut, then ensure the producers are still correct
undoStack->undo();
undoStack->redo();
prod3 = *(timeline->getClipPtr(cid3));
prod4 = *(timeline->getClipPtr(cid4));
// Clips on different tracks shoud not use the same producer
REQUIRE(!prod3.same_clip(prod4));
// Clips on same track shoud use the same producer
REQUIRE(prod1.same_clip(prod3));
REQUIRE(prod2.same_clip(prod4));
}
binModel->clean();
pCore->m_projectManager = nullptr;
}
#include "catch.hpp"
#include "test_utils.hpp"
#include "timeline2/model/snapmodel.hpp"
#include <iostream>
#include <unordered_set>
TEST_CASE("Snap points model test", "[SnapModel]")
{
......
......@@ -26,12 +26,12 @@ QString createProducerWithSound(Mlt::Profile &prof, std::shared_ptr<ProjectItemM
// In case the test system does not have avformat support, we can switch to the integrated blipflash producer
std::shared_ptr<Mlt::Producer> producer = std::make_shared<Mlt::Producer>(prof, "blipflash");
REQUIRE(producer->is_valid());
producer->set("length", length);
producer->set_in_and_out(0, length - 1);
producer->set("kdenlive:duration", length);
REQUIRE(producer->is_valid());
QString binId = QString::number(binModel->getFreeClipId());
auto binClip = ProjectClip::construct(binId, QIcon(), binModel, producer);
binClip->forceLimitedDuration();
......@@ -42,6 +42,25 @@ QString createProducerWithSound(Mlt::Profile &prof, std::shared_ptr<ProjectItemM
return binId;
}
QString createAVProducer(Mlt::Profile &prof, std::shared_ptr<ProjectItemModel> binModel)
{
std::shared_ptr<Mlt::Producer> producer = std::make_shared<Mlt::Producer>(prof, QFileInfo(QCoreApplication::applicationDirPath() + "/../../tests/small.mkv").absoluteFilePath().toStdString().c_str());
// In case the test system does not have avformat support, we can switch to the integrated blipflash producer
/*if (!producer->is_valid()) {
producer.reset(new Mlt::Producer(prof, "blipflash"));
}*/
REQUIRE(producer->is_valid());
QString binId = QString::number(binModel->getFreeClipId());
auto binClip = ProjectClip::construct(binId, QIcon(), binModel, producer);
Fun undo = []() { return true; };
Fun redo = []() { return true; };
REQUIRE(binModel->addItem(binClip, binModel->getRootFolder()->clipId(), undo, redo));
return binId;
}
QString createTextProducer(Mlt::Profile &prof, std::shared_ptr<ProjectItemModel> binModel, int length)
{
std::shared_ptr<Mlt::Producer> producer = std::make_shared<Mlt::Producer>(prof, QFileInfo(QCoreApplication::applicationDirPath() + "/../../tests/dataset/title.kdenlivetitle").absoluteFilePath().toStdString().c_str());
......
......@@ -87,3 +87,5 @@ QString createProducer(Mlt::Profile &prof, std::string color, std::shared_ptr<Pr
QString createProducerWithSound(Mlt::Profile &prof, std::shared_ptr<ProjectItemModel> binModel, int length = 10);
QString createTextProducer(Mlt::Profile &prof, std::shared_ptr<ProjectItemModel> binModel, int length = 10);
QString createAVProducer(Mlt::Profile &prof, std::shared_ptr<ProjectItemModel> binModel);
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment