File indexing completed on 2024-04-21 04:52:51
0001 /* 0002 SPDX-FileCopyrightText: 2018-2022 Jean-Baptiste Mardelle <jb@kdenlive.org> 0003 SPDX-FileCopyrightText: 2022 Eric Jiang 0004 SPDX-License-Identifier: GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL 0005 */ 0006 #include "test_utils.hpp" 0007 // test specific headers 0008 #include "bin/binplaylist.hpp" 0009 #include "doc/kdenlivedoc.h" 0010 #include "timeline2/model/builders/meltBuilder.hpp" 0011 #include "xml/xml.hpp" 0012 0013 #include <QTemporaryFile> 0014 #include <QUndoGroup> 0015 0016 using namespace fakeit; 0017 0018 TEST_CASE("Save File", "[SF]") 0019 { 0020 auto binModel = pCore->projectItemModel(); 0021 binModel->clean(); 0022 std::shared_ptr<DocUndoStack> undoStack = std::make_shared<DocUndoStack>(nullptr); 0023 0024 SECTION("Simple insert and save") 0025 { 0026 // Create document 0027 KdenliveDoc document(undoStack); 0028 pCore->projectManager()->m_project = &document; 0029 QDateTime documentDate = QDateTime::currentDateTime(); 0030 pCore->projectManager()->updateTimeline(false, QString(), QString(), documentDate, 0); 0031 auto timeline = document.getTimeline(document.uuid()); 0032 pCore->projectManager()->testSetActiveDocument(&document, timeline); 0033 KdenliveDoc::next_id = 0; 0034 QDir dir = QDir::temp(); 0035 0036 QString binId = createProducerWithSound(pCore->getProjectProfile(), binModel); 0037 QString binId2 = createProducer(pCore->getProjectProfile(), "red", binModel, 20, false); 0038 0039 int tid1 = timeline->getTrackIndexFromPosition(2); 0040 0041 // Setup timeline audio drop info 0042 QMap<int, QString> audioInfo; 0043 audioInfo.insert(1, QStringLiteral("stream1")); 0044 timeline->m_binAudioTargets = audioInfo; 0045 timeline->m_videoTarget = tid1; 0046 // Insert 2 clips (length=20, pos = 80 / 100) 0047 int cid1 = -1; 0048 REQUIRE(timeline->requestClipInsertion(binId2, tid1, 80, cid1, true, true, false)); 0049 int l = timeline->getClipPlaytime(cid1); 0050 int cid2 = -1; 0051 REQUIRE(timeline->requestClipInsertion(binId2, tid1, 80 + l, cid2, true, true, false)); 0052 // Resize first clip (length=100) 0053 REQUIRE(timeline->requestItemResize(cid1, 100, false) == 100); 0054 0055 auto state = [&]() { 0056 REQUIRE(timeline->checkConsistency()); 0057 REQUIRE(timeline->getTrackClipsCount(tid1) == 2); 0058 REQUIRE(timeline->getClipTrackId(cid1) == tid1); 0059 REQUIRE(timeline->getClipTrackId(cid2) == tid1); 0060 REQUIRE(timeline->getClipPosition(cid1) == 0); 0061 REQUIRE(timeline->getClipPosition(cid2) == 100); 0062 REQUIRE(timeline->getClipPlaytime(cid1) == 100); 0063 REQUIRE(timeline->getClipPlaytime(cid2) == 20); 0064 }; 0065 state(); 0066 REQUIRE(timeline->checkConsistency()); 0067 pCore->projectManager()->testSaveFileAs(dir.absoluteFilePath(QStringLiteral("test.kdenlive"))); 0068 // Undo resize 0069 undoStack->undo(); 0070 // Undo first insert 0071 undoStack->undo(); 0072 // Undo second insert 0073 undoStack->undo(); 0074 pCore->projectManager()->closeCurrentDocument(false, false); 0075 } 0076 SECTION("Reopen and check in/out points") 0077 { 0078 // Create new document 0079 // We mock the project class so that the undoStack function returns our undoStack, and our mocked document 0080 KdenliveDoc::next_id = 0; 0081 QString saveFile = QDir::temp().absoluteFilePath(QStringLiteral("test.kdenlive")); 0082 QUrl openURL = QUrl::fromLocalFile(saveFile); 0083 0084 QUndoGroup *undoGroup = new QUndoGroup(); 0085 undoGroup->addStack(undoStack.get()); 0086 DocOpenResult openResults = KdenliveDoc::Open(openURL, QDir::temp().path(), undoGroup, false, nullptr); 0087 REQUIRE(openResults.isSuccessful() == true); 0088 0089 std::unique_ptr<KdenliveDoc> openedDoc = openResults.getDocument(); 0090 pCore->projectManager()->m_project = openedDoc.get(); 0091 const QUuid uuid = openedDoc->uuid(); 0092 QDateTime documentDate = QFileInfo(openURL.toLocalFile()).lastModified(); 0093 pCore->projectManager()->updateTimeline(false, QString(), QString(), documentDate, 0); 0094 pCore->projectManager()->testSetActiveDocument(openedDoc.get()); 0095 auto timeline = pCore->projectManager()->m_project->getTimeline(uuid); 0096 const QString hash = openedDoc->getSequenceProperty(uuid, QStringLiteral("timelineHash")); 0097 REQUIRE(timeline->getTracksCount() == 4); 0098 REQUIRE(timeline->checkConsistency()); 0099 int tid1 = timeline->getTrackIndexFromPosition(2); 0100 int cid1 = timeline->getClipByStartPosition(tid1, 0); 0101 int cid2 = timeline->getClipByStartPosition(tid1, 100); 0102 REQUIRE(cid1 > -1); 0103 REQUIRE(cid2 > -1); 0104 auto state = [&]() { 0105 REQUIRE(timeline->checkConsistency()); 0106 REQUIRE(timeline->getTrackClipsCount(tid1) == 2); 0107 REQUIRE(timeline->getClipTrackId(cid1) == tid1); 0108 REQUIRE(timeline->getClipTrackId(cid2) == tid1); 0109 REQUIRE(timeline->getClipPosition(cid1) == 0); 0110 REQUIRE(timeline->getClipPosition(cid2) == 100); 0111 REQUIRE(timeline->getClipPlaytime(cid1) == 100); 0112 REQUIRE(timeline->getClipPlaytime(cid2) == 20); 0113 }; 0114 state(); 0115 QByteArray updatedHex = timeline->timelineHash().toHex(); 0116 REQUIRE(updatedHex == hash); 0117 pCore->projectManager()->closeCurrentDocument(false, false); 0118 QDir dir = QDir::temp(); 0119 QFile::remove(dir.absoluteFilePath(QStringLiteral("test.kdenlive"))); 0120 } 0121 SECTION("Open a file with AV clips") 0122 { 0123 // Create new document 0124 QString path = sourcesPath + "/dataset/av.kdenlive"; 0125 QUrl openURL = QUrl::fromLocalFile(path); 0126 0127 QUndoGroup *undoGroup = new QUndoGroup(); 0128 undoGroup->addStack(undoStack.get()); 0129 DocOpenResult openResults = KdenliveDoc::Open(openURL, QDir::temp().path(), undoGroup, false, nullptr); 0130 REQUIRE(openResults.isSuccessful() == true); 0131 std::unique_ptr<KdenliveDoc> openedDoc = openResults.getDocument(); 0132 0133 pCore->projectManager()->m_project = openedDoc.get(); 0134 const QUuid uuid = openedDoc->uuid(); 0135 QDateTime documentDate = QFileInfo(openURL.toLocalFile()).lastModified(); 0136 pCore->projectManager()->updateTimeline(false, QString(), QString(), documentDate, 0); 0137 auto timeline = pCore->projectManager()->m_project->getTimeline(uuid); 0138 pCore->projectManager()->testSetActiveDocument(openedDoc.get(), timeline); 0139 0140 REQUIRE(timeline->checkConsistency()); 0141 int tid1 = timeline->getTrackIndexFromPosition(0); 0142 int tid2 = timeline->getTrackIndexFromPosition(1); 0143 int tid3 = timeline->getTrackIndexFromPosition(2); 0144 int tid4 = timeline->getTrackIndexFromPosition(3); 0145 // Check we have audio and video tracks 0146 REQUIRE(timeline->isAudioTrack(tid1)); 0147 REQUIRE(timeline->isAudioTrack(tid2)); 0148 REQUIRE(timeline->isAudioTrack(tid3) == false); 0149 REQUIRE(timeline->isAudioTrack(tid4) == false); 0150 int cid1 = timeline->getClipByStartPosition(tid1, 0); 0151 int cid2 = timeline->getClipByStartPosition(tid2, 0); 0152 int cid3 = timeline->getClipByStartPosition(tid3, 0); 0153 int cid4 = timeline->getClipByStartPosition(tid4, 0); 0154 // Check we have our clips 0155 REQUIRE(cid1 == -1); 0156 REQUIRE(cid2 > -1); 0157 REQUIRE(cid3 > -1); 0158 REQUIRE(cid4 == -1); 0159 REQUIRE(timeline->getClipPlaytime(cid2) == 500); 0160 REQUIRE(timeline->getClipPlaytime(cid3) == 500); 0161 pCore->projectManager()->closeCurrentDocument(false, false); 0162 } 0163 } 0164 0165 TEST_CASE("Check File Corruption", "[CFC]") 0166 { 0167 auto binModel = pCore->projectItemModel(); 0168 binModel->clean(); 0169 std::shared_ptr<DocUndoStack> undoStack = std::make_shared<DocUndoStack>(nullptr); 0170 0171 SECTION("Open a file and check id consistency") 0172 { 0173 // open 0174 QString path = sourcesPath + "/dataset/clip-ids.kdenlive"; 0175 QUrl openURL = QUrl::fromLocalFile(path); 0176 0177 QUndoGroup *undoGroup = new QUndoGroup(); 0178 undoGroup->addStack(undoStack.get()); 0179 DocOpenResult openResults = KdenliveDoc::Open(openURL, QDir::temp().path(), undoGroup, false, nullptr); 0180 REQUIRE(openResults.isSuccessful() == true); 0181 0182 std::unique_ptr<KdenliveDoc> openedDoc = openResults.getDocument(); 0183 // Mock<KdenliveDoc> docMock(*openedDoc.get()); 0184 // When(Method(docMock, getCacheDir)).AlwaysReturn(QDir(QStandardPaths::writableLocation(QStandardPaths::CacheLocation))); 0185 // KdenliveDoc &mockedDoc = docMock.get(); 0186 pCore->projectManager()->m_project = openedDoc.get(); 0187 const QUuid uuid = openedDoc->uuid(); 0188 QDateTime documentDate = QFileInfo(openURL.toLocalFile()).lastModified(); 0189 pCore->projectManager()->updateTimeline(false, QString(), QString(), documentDate, 0); 0190 0191 QMap<QUuid, QString> allSequences = binModel->getAllSequenceClips(); 0192 const QString firstSeqId = allSequences.value(uuid); 0193 pCore->projectManager()->openTimeline(firstSeqId, uuid); 0194 std::shared_ptr<TimelineItemModel> timeline = openedDoc->getTimeline(uuid); 0195 pCore->projectManager()->testSetActiveDocument(openedDoc.get(), timeline); 0196 0197 // Now reopen all timeline sequences 0198 QList<QUuid> allUuids = allSequences.keys(); 0199 allUuids.removeAll(uuid); 0200 for (auto &u : allUuids) { 0201 const QString id = allSequences.value(u); 0202 pCore->projectManager()->openTimeline(id, u); 0203 } 0204 0205 // std::shared_ptr<TimelineItemModel> timeline = openedDoc->getTimeline(uuid); 0206 // pCore->projectManager()->testSetActiveDocument(&mockedDoc); 0207 // auto timeline = mockedDoc.getTimeline(uuid); 0208 0209 REQUIRE(timeline->checkConsistency()); 0210 int tid1 = timeline->getTrackIndexFromPosition(0); 0211 int tid2 = timeline->getTrackIndexFromPosition(1); 0212 int tid3 = timeline->getTrackIndexFromPosition(2); 0213 int tid4 = timeline->getTrackIndexFromPosition(3); 0214 // Check we have audio and video tracks 0215 REQUIRE(timeline->isAudioTrack(tid1)); 0216 REQUIRE(timeline->isAudioTrack(tid2)); 0217 REQUIRE(timeline->isAudioTrack(tid3) == false); 0218 REQUIRE(timeline->isAudioTrack(tid4) == false); 0219 int cid1 = timeline->getClipByStartPosition(tid4, 16); // Blue 0220 int cid2 = timeline->getClipByStartPosition(tid4, 21); // Green 0221 int cid3 = timeline->getClipByStartPosition(tid4, 26); // Red 0222 int cid4 = timeline->getClipByStartPosition(tid4, 31); // Yellow 0223 int cid1b = timeline->getClipByStartPosition(tid3, 11); // Blue 0224 int cid2b = timeline->getClipByStartPosition(tid3, 16); // Green 0225 int cid3b = timeline->getClipByStartPosition(tid3, 21); // Red 0226 int cid4b = timeline->getClipByStartPosition(tid3, 26); // Yellow 0227 // Check we have our clips 0228 REQUIRE(cid1 > -1); 0229 REQUIRE(cid2 > -1); 0230 REQUIRE(cid3 > -1); 0231 REQUIRE(cid4 > -1); 0232 REQUIRE(cid1b > -1); 0233 REQUIRE(cid2b > -1); 0234 REQUIRE(cid3b > -1); 0235 REQUIRE(cid4b > -1); 0236 REQUIRE(timeline->getClipPtr(cid1)->clipName() == QLatin1String("blue.mpg")); 0237 REQUIRE(timeline->getClipPtr(cid1b)->clipName() == QLatin1String("blue.mpg")); 0238 REQUIRE(timeline->getClipPtr(cid2)->clipName() == QLatin1String("green.mpg")); 0239 REQUIRE(timeline->getClipPtr(cid2b)->clipName() == QLatin1String("green.mpg")); 0240 REQUIRE(timeline->getClipPtr(cid3)->clipName() == QLatin1String("red.mpg")); 0241 REQUIRE(timeline->getClipPtr(cid3b)->clipName() == QLatin1String("red.mpg")); 0242 REQUIRE(timeline->getClipPtr(cid4)->clipName() == QLatin1String("yellow.mpg")); 0243 REQUIRE(timeline->getClipPtr(cid4b)->clipName() == QLatin1String("yellow.mpg")); 0244 pCore->projectManager()->closeCurrentDocument(false, false); 0245 } 0246 } 0247 0248 TEST_CASE("Non-BMP Unicode", "[NONBMP]") 0249 { 0250 auto binModel = pCore->projectItemModel(); 0251 binModel->clean(); 0252 0253 // A Kdenlive bug (bugzilla bug 435768) caused characters outside the Basic 0254 // Multilingual Plane to be lost when the file is loaded. This string 0255 // contains the onigiri emoji which should survive a save+open round trip. 0256 // If Kdenlive drops the emoji, then the result is just "testtest" which can 0257 // be checked for. 0258 0259 const QString emojiTestString = QString::fromUtf8("test\xF0\x9F\x8D\x99test"); 0260 std::shared_ptr<DocUndoStack> undoStack = std::make_shared<DocUndoStack>(nullptr); 0261 0262 QTemporaryFile saveFile(QDir::temp().filePath("kdenlive_test_XXXXXX.kdenlive")); 0263 qDebug() << "Choosing temp file with template" << (QDir::temp().filePath("kdenlive_test_XXXXXX.kdenlive")); 0264 REQUIRE(saveFile.open()); 0265 saveFile.close(); 0266 qDebug() << "New temporary file:" << saveFile.fileName(); 0267 0268 SECTION("Save title with special chars") 0269 { 0270 // Create document 0271 KdenliveDoc document(undoStack); 0272 pCore->projectManager()->m_project = &document; 0273 QDateTime documentDate = QDateTime::currentDateTime(); 0274 pCore->projectManager()->updateTimeline(false, QString(), QString(), documentDate, 0); 0275 auto timeline = document.getTimeline(document.uuid()); 0276 pCore->projectManager()->m_activeTimelineModel = timeline; 0277 pCore->projectManager()->testSetActiveDocument(&document, timeline); 0278 QDir dir = QDir::temp(); 0279 0280 // create a simple title with the non-BMP test string 0281 const QString titleXml = 0282 QString("<kdenlivetitle duration=\"150\" LC_NUMERIC=\"C\" width=\"1920\" height=\"1080\" out=\"149\">\n <item type=\"QGraphicsTextItem\" " 0283 "z-index=\"0\">\n <position x=\"777\" y=\"482\">\n <transform>1,0,0,0,1,0,0,0,1</transform>\n </position>\n <content " 0284 "shadow=\"0;#64000000;3;3;3\" font-underline=\"0\" box-height=\"138\" font-outline-color=\"0,0,0,255\" font=\"DejaVu Sans\" " 0285 "letter-spacing=\"0\" font-pixel-size=\"120\" font-italic=\"0\" typewriter=\"0;2;1;0;0\" alignment=\"0\" font-weight=\"63\" " 0286 "font-outline=\"3\" box-width=\"573.25\" font-color=\"252,233,79,255\">") + 0287 emojiTestString + 0288 QString("</content>\n </item>\n <startviewport rect=\"0,0,1920,1080\"/>\n <endviewport rect=\"0,0,1920,1080\"/>\n <background " 0289 "color=\"0,0,0,0\"/>\n</kdenlivetitle>\n"); 0290 0291 QString binId2 = createTextProducer(pCore->getProjectProfile(), binModel, titleXml, emojiTestString, 150); 0292 0293 TrackModel::construct(timeline, -1, -1, QString(), true); 0294 TrackModel::construct(timeline, -1, -1, QString(), true); 0295 int tid1 = timeline->getTrackIndexFromPosition(2); 0296 0297 // Setup timeline audio drop info 0298 QMap<int, QString> audioInfo; 0299 audioInfo.insert(1, QStringLiteral("stream1")); 0300 timeline->m_binAudioTargets = audioInfo; 0301 timeline->m_videoTarget = tid1; 0302 0303 pCore->projectManager()->testSaveFileAs(saveFile.fileName()); 0304 0305 // open the file and check that it contains emojiTestString 0306 QFile file(saveFile.fileName()); 0307 REQUIRE(file.open(QIODevice::ReadOnly)); 0308 QByteArray contents = file.readAll(); 0309 if (contents.contains(emojiTestString.toUtf8())) { 0310 qDebug() << "File contains test string"; 0311 } else { 0312 qDebug() << "File does not contain test string:" << contents; 0313 } 0314 REQUIRE(contents.contains(emojiTestString.toUtf8())); 0315 0316 // try opening the file as a Kdenlivedoc and check that the title hasn't 0317 // lost the emoji 0318 0319 QUrl openURL = QUrl::fromLocalFile(saveFile.fileName()); 0320 QUndoGroup *undoGroup = new QUndoGroup(); 0321 undoGroup->addStack(undoStack.get()); 0322 DocOpenResult openResults = KdenliveDoc::Open(openURL, QDir::temp().path(), 0323 undoGroup, false, nullptr); 0324 REQUIRE(openResults.isSuccessful() == true); 0325 0326 std::unique_ptr<KdenliveDoc> openedDoc = openResults.getDocument(); 0327 QDomDocument *newDoc = &openedDoc->m_document; 0328 auto producers = newDoc->elementsByTagName(QStringLiteral("producer")); 0329 QDomElement textTitle; 0330 for (int i = 0; i < producers.size(); i++) { 0331 auto kdenliveid = getProperty(producers.at(i).toElement(), QStringLiteral("kdenlive:id")); 0332 if (kdenliveid != nullptr && kdenliveid->text() == binId2) { 0333 textTitle = producers.at(i).toElement(); 0334 break; 0335 } 0336 } 0337 auto clipname = getProperty(textTitle, QStringLiteral("kdenlive:clipname")); 0338 REQUIRE(clipname != nullptr); 0339 CHECK(clipname->text() == emojiTestString); 0340 auto xmldata = getProperty(textTitle, QStringLiteral("xmldata")); 0341 REQUIRE(xmldata != nullptr); 0342 CHECK(clipname->text().contains(emojiTestString)); 0343 pCore->projectManager()->closeCurrentDocument(false, false); 0344 } 0345 0346 SECTION("Save project and check profile") 0347 { 0348 0349 // Create document 0350 pCore->setCurrentProfile(QStringLiteral("atsc_1080p_25")); 0351 KdenliveDoc document(undoStack); 0352 0353 // We mock the project class so that the undoStack function returns our undoStack, and our mocked document 0354 pCore->projectManager()->m_project = &document; 0355 QDateTime documentDate = QDateTime::currentDateTime(); 0356 pCore->projectManager()->updateTimeline(false, QString(), QString(), documentDate, 0); 0357 auto timeline = document.getTimeline(document.uuid()); 0358 pCore->projectManager()->testSetActiveDocument(&document, timeline); 0359 0360 QDir dir = QDir::temp(); 0361 int tid1 = timeline->getTrackIndexFromPosition(2); 0362 0363 // Setup timeline audio drop info 0364 QMap<int, QString> audioInfo; 0365 audioInfo.insert(1, QStringLiteral("stream1")); 0366 timeline->m_binAudioTargets = audioInfo; 0367 timeline->m_videoTarget = tid1; 0368 0369 pCore->projectManager()->testSaveFileAs(saveFile.fileName()); 0370 0371 // open the file and check that it contains the correct profile info 0372 QFile file(saveFile.fileName()); 0373 REQUIRE(file.open(QIODevice::ReadOnly)); 0374 QByteArray contents = file.readAll(); 0375 QString contentCheck("<property name=\"kdenlive:docproperties.profile\">atsc_1080p_25</property>"); 0376 if (contents.contains(contentCheck.toUtf8())) { 0377 qDebug() << "File contains test string"; 0378 } else { 0379 qDebug() << "File does not contain test string:" << contents; 0380 } 0381 REQUIRE(contents.contains(contentCheck.toUtf8())); 0382 pCore->projectManager()->closeCurrentDocument(false, false); 0383 } 0384 } 0385 0386 TEST_CASE("Opening Mix", "[OPENMIX]") 0387 { 0388 auto binModel = pCore->projectItemModel(); 0389 binModel->clean(); 0390 0391 // Check that mixes (and reverse mixes) load correctly 0392 0393 const QString emojiTestString = QString::fromUtf8("test\xF0\x9F\x8D\x99test"); 0394 0395 std::shared_ptr<DocUndoStack> undoStack = std::make_shared<DocUndoStack>(nullptr); 0396 0397 SECTION("Load file with a mix") 0398 { 0399 // We mock the project class so that the undoStack function returns our undoStack, and our mocked document 0400 QUrl openURL = QUrl::fromLocalFile(sourcesPath + "/dataset/test-mix.kdenlive"); 0401 0402 QUndoGroup *undoGroup = new QUndoGroup(); 0403 undoGroup->addStack(undoStack.get()); 0404 DocOpenResult openResults = KdenliveDoc::Open(openURL, QDir::temp().path(), undoGroup, false, nullptr); 0405 REQUIRE(openResults.isSuccessful() == true); 0406 0407 std::unique_ptr<KdenliveDoc> openedDoc = openResults.getDocument(); 0408 0409 pCore->projectManager()->m_project = openedDoc.get(); 0410 const QUuid uuid = openedDoc->uuid(); 0411 QDateTime documentDate = QFileInfo(openURL.toLocalFile()).lastModified(); 0412 pCore->projectManager()->updateTimeline(false, QString(), QString(), documentDate, 0); 0413 auto timeline = openedDoc->getTimeline(uuid); 0414 pCore->projectManager()->testSetActiveDocument(openedDoc.get(), timeline); 0415 0416 REQUIRE(timeline->getTracksCount() == 4); 0417 int mixtrackId = timeline->getTrackIndexFromPosition(2); 0418 REQUIRE(timeline->getTrackById_const(mixtrackId)->mixCount() == 2); 0419 int mixtrackId2 = timeline->getTrackIndexFromPosition(3); 0420 REQUIRE(timeline->getTrackById_const(mixtrackId2)->mixCount() == 1); 0421 0422 QDomDocument *newDoc = &openedDoc->m_document; 0423 auto producers = newDoc->elementsByTagName(QStringLiteral("producer")); 0424 pCore->projectManager()->closeCurrentDocument(false, false); 0425 } 0426 } 0427 0428 TEST_CASE("Opening File With Keyframes", "[OPENKFRS]") 0429 { 0430 auto binModel = pCore->projectItemModel(); 0431 binModel->clean(); 0432 std::shared_ptr<DocUndoStack> undoStack = std::make_shared<DocUndoStack>(nullptr); 0433 0434 SECTION("Open a file with Keyframes") 0435 { 0436 // Create new document 0437 QString path = sourcesPath + "/dataset/test-keyframes.kdenlive"; 0438 QUrl openURL = QUrl::fromLocalFile(path); 0439 0440 QUndoGroup *undoGroup = new QUndoGroup(); 0441 undoGroup->addStack(undoStack.get()); 0442 DocOpenResult openResults = KdenliveDoc::Open(openURL, QDir::temp().path(), undoGroup, false, nullptr); 0443 REQUIRE(openResults.isSuccessful() == true); 0444 std::unique_ptr<KdenliveDoc> openedDoc = openResults.getDocument(); 0445 0446 pCore->projectManager()->m_project = openedDoc.get(); 0447 const QUuid uuid = openedDoc->uuid(); 0448 QDateTime documentDate = QFileInfo(openURL.toLocalFile()).lastModified(); 0449 pCore->projectManager()->updateTimeline(false, QString(), QString(), documentDate, 0); 0450 pCore->projectManager()->testSetActiveDocument(openedDoc.get()); 0451 auto timeline = pCore->projectManager()->m_project->getTimeline(uuid); 0452 0453 REQUIRE(timeline->checkConsistency()); 0454 int tid1 = timeline->getTrackIndexFromPosition(0); 0455 int tid2 = timeline->getTrackIndexFromPosition(1); 0456 int tid3 = timeline->getTrackIndexFromPosition(2); 0457 int tid4 = timeline->getTrackIndexFromPosition(3); 0458 // Check we have audio and video tracks 0459 REQUIRE(timeline->isAudioTrack(tid1)); 0460 REQUIRE(timeline->isAudioTrack(tid2)); 0461 REQUIRE(timeline->isAudioTrack(tid3) == false); 0462 REQUIRE(timeline->isAudioTrack(tid4) == false); 0463 int cid1 = timeline->getClipByStartPosition(tid1, 0); 0464 int cid2 = timeline->getClipByStartPosition(tid2, 0); 0465 int cid3 = timeline->getClipByStartPosition(tid3, 0); 0466 int cid4 = timeline->getClipByStartPosition(tid4, 0); 0467 // Check we have our clips 0468 REQUIRE(cid1 == -1); 0469 REQUIRE(cid2 > -1); 0470 REQUIRE(cid3 > -1); 0471 REQUIRE(cid4 == -1); 0472 pCore->projectManager()->closeCurrentDocument(false, false); 0473 } 0474 }