File indexing completed on 2024-04-07 04:45:11

0001 /*
0002     SPDX-FileCopyrightText: 2022 Jean-Baptiste Mardelle <jb@kdenlive.org>
0003     SPDX-License-Identifier: GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
0004 */
0005 #include "catch.hpp"
0006 #include "test_utils.hpp"
0007 // test specific headers
0008 #include "core.h"
0009 #include "definitions.h"
0010 #include "doc/docundostack.hpp"
0011 #include "doc/kdenlivedoc.h"
0012 
0013 using namespace fakeit;
0014 
0015 TEST_CASE("Remove all spaces", "[Spacer]")
0016 {
0017     // Create timeline
0018     auto binModel = pCore->projectItemModel();
0019     binModel->clean();
0020     std::shared_ptr<DocUndoStack> undoStack = std::make_shared<DocUndoStack>(nullptr);
0021 
0022     // Here we do some trickery to enable testing.
0023     KdenliveDoc document(undoStack, {1, 2});
0024     pCore->projectManager()->m_project = &document;
0025     QDateTime documentDate = QDateTime::currentDateTime();
0026     pCore->projectManager()->updateTimeline(false, QString(), QString(), documentDate, 0);
0027     auto timeline = document.getTimeline(document.uuid());
0028     pCore->projectManager()->m_activeTimelineModel = timeline;
0029     pCore->projectManager()->testSetActiveDocument(&document, timeline);
0030 
0031     int tid1 = timeline->getTrackIndexFromPosition(2);
0032     int tid2 = timeline->getTrackIndexFromPosition(1);
0033 
0034     // Create clip with audio (40 frames long)
0035     QString binId = createProducer(pCore->getProjectProfile(), "red", binModel, 20);
0036     QString avBinId = createProducerWithSound(pCore->getProjectProfile(), binModel, 100);
0037 
0038     // Setup insert stream data
0039     QMap<int, QString> audioInfo;
0040     audioInfo.insert(1, QStringLiteral("stream1"));
0041     timeline->m_binAudioTargets = audioInfo;
0042 
0043     // Create clips in timeline
0044     int cid1;
0045     int cid2;
0046     int cid3;
0047     int cid4;
0048     REQUIRE(timeline->requestClipInsertion(binId, tid1, 10, cid1));
0049     REQUIRE(timeline->requestClipInsertion(binId, tid1, 80, cid2));
0050     REQUIRE(timeline->requestClipInsertion(binId, tid1, 101, cid3));
0051     REQUIRE(timeline->requestClipInsertion(binId, tid2, 20, cid4));
0052 
0053     auto state1 = [&]() {
0054         REQUIRE(timeline->checkConsistency());
0055         REQUIRE(timeline->getTrackClipsCount(tid1) == 3);
0056         REQUIRE(timeline->getTrackClipsCount(tid2) == 1);
0057         REQUIRE(timeline->getClipsCount() == 4);
0058         REQUIRE(timeline->getClipPosition(cid1) == 10);
0059         REQUIRE(timeline->getClipPosition(cid2) == 80);
0060         REQUIRE(timeline->getClipPosition(cid3) == 101);
0061         REQUIRE(timeline->getClipPosition(cid4) == 20);
0062     };
0063 
0064     SECTION("Ensure remove spaces behaves correctly")
0065     {
0066         // We have clips at 10, 80, 101 on track 1 (length 20 frames each)
0067         // One clip at 20 on track 2
0068         REQUIRE(TimelineFunctions::requestDeleteAllBlanksFrom(timeline, tid1, 20));
0069         REQUIRE(timeline->getTrackClipsCount(tid1) == 3);
0070         REQUIRE(timeline->getTrackClipsCount(tid2) == 1);
0071         REQUIRE(timeline->getClipsCount() == 4);
0072         REQUIRE(timeline->getClipPosition(cid1) == 10);
0073         REQUIRE(timeline->getClipPosition(cid2) == 30);
0074         REQUIRE(timeline->getClipPosition(cid3) == 50);
0075         REQUIRE(timeline->getClipPosition(cid4) == 20);
0076         undoStack->undo();
0077         state1();
0078     }
0079     SECTION("Ensure remove spaces behaves correctly with a group")
0080     {
0081         // We have clips at 10, 80, 101 on track 1 (length 20 frames each)
0082         // One clip at 20 on track 2
0083         std::unordered_set<int> ids = {cid2, cid3};
0084         int gid = timeline->requestClipsGroup(ids);
0085         REQUIRE(gid > -1);
0086         REQUIRE(TimelineFunctions::requestDeleteAllBlanksFrom(timeline, tid1, 20));
0087         REQUIRE(timeline->getTrackClipsCount(tid1) == 3);
0088         REQUIRE(timeline->getTrackClipsCount(tid2) == 1);
0089         REQUIRE(timeline->getClipsCount() == 4);
0090         REQUIRE(timeline->getClipPosition(cid1) == 10);
0091         REQUIRE(timeline->getClipPosition(cid2) == 30);
0092         REQUIRE(timeline->getClipPosition(cid3) == 51);
0093         REQUIRE(timeline->getClipPosition(cid4) == 20);
0094         undoStack->undo();
0095         state1();
0096         undoStack->undo();
0097     }
0098     SECTION("Ensure remove spaces behaves correctly with a group on different tracks")
0099     {
0100         // We have clips at 10, 80, 101 on track 1 (length 20 frames each)
0101         // One clip at 20 on track 2
0102         // Grouping clip at 80 on tid1 and at 20 on tid2, so the group move will be rejected for the 80 clip
0103         std::unordered_set<int> ids = {cid2, cid4};
0104         int gid = timeline->requestClipsGroup(ids);
0105         REQUIRE(gid > -1);
0106         REQUIRE(TimelineFunctions::requestDeleteAllBlanksFrom(timeline, tid1, 20));
0107         REQUIRE(timeline->getTrackClipsCount(tid1) == 3);
0108         REQUIRE(timeline->getTrackClipsCount(tid2) == 1);
0109         REQUIRE(timeline->getClipsCount() == 4);
0110         REQUIRE(timeline->getClipPosition(cid1) == 10);
0111         REQUIRE(timeline->getClipPosition(cid2) == 80);
0112         REQUIRE(timeline->getClipPosition(cid3) == 100);
0113         REQUIRE(timeline->getClipPosition(cid4) == 20);
0114         undoStack->undo();
0115         state1();
0116         undoStack->undo();
0117     }
0118     SECTION("Ensure remove spaces behaves correctly with a group on different tracks")
0119     {
0120         // We have clips at 10, 80, 101 on track 1 (length 20 frames each)
0121         // One clip at 20 on track 2
0122         // Grouping clip at 10 on tid1 and at 20 on tid2, so the clip on tid2 will be moved
0123         std::unordered_set<int> ids = {cid1, cid4};
0124         int gid = timeline->requestClipsGroup(ids);
0125         REQUIRE(gid > -1);
0126         REQUIRE(TimelineFunctions::requestDeleteAllBlanksFrom(timeline, tid1, 0));
0127         REQUIRE(timeline->getTrackClipsCount(tid1) == 3);
0128         REQUIRE(timeline->getTrackClipsCount(tid2) == 1);
0129         REQUIRE(timeline->getClipsCount() == 4);
0130         REQUIRE(timeline->getClipPosition(cid1) == 0);
0131         REQUIRE(timeline->getClipPosition(cid2) == 20);
0132         REQUIRE(timeline->getClipPosition(cid3) == 40);
0133         REQUIRE(timeline->getClipPosition(cid4) == 10);
0134         undoStack->undo();
0135         state1();
0136         undoStack->undo();
0137     }
0138     SECTION("Ensure remove all clips on track behaves correctly")
0139     {
0140         // We have clips at 10, 80, 101 on track 1 (length 20 frames each)
0141         // One clip at 20 on track 2
0142         // Grouping clip at 10 on tid1 and at 20 on tid2, so the clip on tid2 will be moved
0143         std::unordered_set<int> ids = {cid1, cid4};
0144         int gid = timeline->requestClipsGroup(ids);
0145         REQUIRE(gid > -1);
0146         REQUIRE(TimelineFunctions::requestDeleteAllClipsFrom(timeline, tid1, 80));
0147         REQUIRE(timeline->getTrackClipsCount(tid1) == 1);
0148         REQUIRE(timeline->getTrackClipsCount(tid2) == 1);
0149         undoStack->undo();
0150         state1();
0151         REQUIRE(TimelineFunctions::requestDeleteAllClipsFrom(timeline, tid1, 20));
0152         REQUIRE(timeline->getTrackClipsCount(tid1) == 0);
0153         REQUIRE(timeline->getTrackClipsCount(tid2) == 0);
0154         undoStack->undo();
0155         state1();
0156         undoStack->undo();
0157     }
0158     SECTION("Ensure delete blank works correctly with grouped clips")
0159     {
0160         // We have clips at 10, 80, 101 on track 1 (length 20 frames each)
0161         // One clip at 20 on track 2
0162         // Grouping clip at 80 and 101 on tid1
0163         std::unordered_set<int> ids = {cid2, cid3};
0164         int gid = timeline->requestClipsGroup(ids);
0165         REQUIRE(gid > -1);
0166         REQUIRE(TimelineFunctions::requestDeleteBlankAt(timeline, tid1, 80, false) == false);
0167         REQUIRE(TimelineFunctions::requestDeleteBlankAt(timeline, tid1, 70, false));
0168         REQUIRE(timeline->getTrackClipsCount(tid1) == 3);
0169         REQUIRE(timeline->getTrackClipsCount(tid2) == 1);
0170         REQUIRE(timeline->getClipPosition(cid1) == 10);
0171         REQUIRE(timeline->getClipPosition(cid2) == 30);
0172         REQUIRE(timeline->getClipPosition(cid3) == 51);
0173         REQUIRE(timeline->getClipPosition(cid4) == 20);
0174         undoStack->undo();
0175         state1();
0176         // Delete space between 2 grouped clips, should fail
0177         REQUIRE(TimelineFunctions::requestDeleteBlankAt(timeline, tid1, 100, false) == false);
0178         undoStack->undo();
0179     }
0180     SECTION("Ensure delete blank works correctly with ungrouped clips")
0181     {
0182         // We have clips at 10, 80, 101 on track 1 (length 20 frames each)
0183         // One clip at 20 on track 2
0184         REQUIRE(TimelineFunctions::requestDeleteBlankAt(timeline, tid1, 5, false));
0185         REQUIRE(timeline->getTrackClipsCount(tid1) == 3);
0186         REQUIRE(timeline->getTrackClipsCount(tid2) == 1);
0187         REQUIRE(timeline->getClipPosition(cid1) == 0);
0188         REQUIRE(timeline->getClipPosition(cid2) == 70);
0189         REQUIRE(timeline->getClipPosition(cid3) == 91);
0190         REQUIRE(timeline->getClipPosition(cid4) == 20);
0191         undoStack->undo();
0192         REQUIRE(TimelineFunctions::requestDeleteBlankAt(timeline, tid1, 5, true));
0193         REQUIRE(timeline->getTrackClipsCount(tid1) == 3);
0194         REQUIRE(timeline->getTrackClipsCount(tid2) == 1);
0195         REQUIRE(timeline->getClipPosition(cid1) == 0);
0196         REQUIRE(timeline->getClipPosition(cid2) == 70);
0197         REQUIRE(timeline->getClipPosition(cid3) == 91);
0198         REQUIRE(timeline->getClipPosition(cid4) == 10);
0199         undoStack->undo();
0200         REQUIRE(TimelineFunctions::requestDeleteBlankAt(timeline, tid1, 60, false));
0201         REQUIRE(timeline->getTrackClipsCount(tid1) == 3);
0202         REQUIRE(timeline->getTrackClipsCount(tid2) == 1);
0203         REQUIRE(timeline->getClipPosition(cid1) == 10);
0204         REQUIRE(timeline->getClipPosition(cid2) == 30);
0205         REQUIRE(timeline->getClipPosition(cid3) == 51);
0206         REQUIRE(timeline->getClipPosition(cid4) == 20);
0207         undoStack->undo();
0208         state1();
0209     }
0210     SECTION("Insert space test with ungrouped clips")
0211     {
0212         // We have clips at 10, 80, 101 on track 1 (length 20 frames each)
0213         // One clip at 20 on track 2
0214         // operation on one track (tid1)
0215         std::pair<int, int> spacerOp = TimelineFunctions::requestSpacerStartOperation(timeline, tid1, 40);
0216         int cid = spacerOp.first;
0217         REQUIRE(cid > -1);
0218         Fun undo = []() { return true; };
0219         Fun redo = []() { return true; };
0220         int start = timeline->getItemPosition(cid);
0221         REQUIRE(TimelineFunctions::requestSpacerEndOperation(timeline, cid, start, start + 100, tid1, -1, undo, redo));
0222         REQUIRE(timeline->getTrackClipsCount(tid1) == 3);
0223         REQUIRE(timeline->getTrackClipsCount(tid2) == 1);
0224         REQUIRE(timeline->getClipPosition(cid1) == 10);
0225         REQUIRE(timeline->getClipPosition(cid2) == 180);
0226         REQUIRE(timeline->getClipPosition(cid3) == 201);
0227         REQUIRE(timeline->getClipPosition(cid4) == 20);
0228         undoStack->undo();
0229         state1();
0230         // operation on all tracks
0231         /*spacerOp = TimelineFunctions::requestSpacerStartOperation(timeline, -1, 35);
0232         cid = spacerOp.first;
0233         REQUIRE(cid > -1);
0234         start = timeline->getItemPosition(cid);
0235         REQUIRE(TimelineFunctions::requestSpacerEndOperation(timeline, cid, start, start + 100, -1, -1, undo, redo));
0236         REQUIRE(timeline->getTrackClipsCount(tid1) == 3);
0237         REQUIRE(timeline->getTrackClipsCount(tid2) == 1);
0238         REQUIRE(timeline->getClipPosition(cid1) == 10);
0239         REQUIRE(timeline->getClipPosition(cid2) == 180);
0240         REQUIRE(timeline->getClipPosition(cid3) == 201);
0241         REQUIRE(timeline->getClipPosition(cid4) == 120);
0242         undoStack->undo();
0243         state1();*/
0244     }
0245     pCore->projectManager()->closeCurrentDocument(false, false);
0246 }