1 #include "test_utils.hpp" 2 3 using namespace fakeit; 4 Mlt::Profile profile_timewarp; 5 6 TEST_CASE("Test of timewarping", "[Timewarp]") 7 { 8 auto binModel = pCore->projectItemModel(); 9 binModel->clean(); 10 std::shared_ptr<DocUndoStack> undoStack = std::make_shared<DocUndoStack>(nullptr); 11 std::shared_ptr<MarkerListModel> guideModel = std::make_shared<MarkerListModel>(undoStack); 12 13 // Here we do some trickery to enable testing. 14 // We mock the project class so that the undoStack function returns our undoStack 15 16 Mock<ProjectManager> pmMock; 17 When(Method(pmMock, undoStack)).AlwaysReturn(undoStack); 18 When(Method(pmMock, cacheDir)).AlwaysReturn(QDir(QStandardPaths::writableLocation(QStandardPaths::CacheLocation))); 19 20 ProjectManager &mocked = pmMock.get(); 21 pCore->m_projectManager = &mocked; 22 23 // We also mock timeline object to spy few functions and mock others 24 TimelineItemModel tim(&profile_timewarp, undoStack); 25 Mock<TimelineItemModel> timMock(tim); __anon90cc78240102(...) 26 auto timeline = std::shared_ptr<TimelineItemModel>(&timMock.get(), [](...) {}); 27 TimelineItemModel::finishConstruct(timeline, guideModel); 28 29 RESET(timMock); 30 TimelineModel::next_id = 0; 31 undoStack->undo(); 32 undoStack->redo(); 33 undoStack->redo(); 34 undoStack->undo(); 35 36 QString binId = createProducer(profile_timewarp, "red", binModel); 37 QString binId2 = createProducer(profile_timewarp, "blue", binModel); 38 QString binId3 = createProducerWithSound(profile_timewarp, binModel); 39 40 int cid1 = ClipModel::construct(timeline, binId, -1, PlaylistState::VideoOnly); 41 int tid1 = TrackModel::construct(timeline); 42 int tid2 = TrackModel::construct(timeline); 43 Q_UNUSED(tid1); 44 Q_UNUSED(tid2); 45 int cid2 = ClipModel::construct(timeline, binId2, -1, PlaylistState::VideoOnly); 46 int cid3 = ClipModel::construct(timeline, binId3, -1, PlaylistState::VideoOnly); 47 48 timeline->m_allClips[cid1]->m_endlessResize = false; 49 timeline->m_allClips[cid2]->m_endlessResize = false; 50 timeline->m_allClips[cid3]->m_endlessResize = false; 51 52 SECTION("Timewarping orphan clip") 53 { 54 int originalDuration = timeline->getClipPlaytime(cid3); 55 REQUIRE(timeline->checkConsistency()); 56 REQUIRE(timeline->getClipTrackId(cid3) == -1); 57 REQUIRE(timeline->getClipSpeed(cid3) == 1.); 58 __anon90cc78240202() 59 std::function<bool(void)> undo = []() { return true; }; __anon90cc78240302() 60 std::function<bool(void)> redo = []() { return true; }; 61 62 REQUIRE(timeline->requestClipTimeWarp(cid3, 0.1, false, true, undo, redo)); 63 64 REQUIRE(timeline->getClipSpeed(cid3) == 0.1); 65 INFO(timeline->m_allClips[cid3]->getIn()); 66 INFO(timeline->m_allClips[cid3]->getOut()); 67 REQUIRE(timeline->getClipPlaytime(cid3) == originalDuration / 0.1); 68 69 undo(); 70 71 REQUIRE(timeline->getClipSpeed(cid3) == 1.); 72 REQUIRE(timeline->getClipPlaytime(cid3) == originalDuration); 73 74 redo(); 75 76 REQUIRE(timeline->getClipSpeed(cid3) == 0.1); 77 REQUIRE(timeline->getClipPlaytime(cid3) == originalDuration / 0.1); 78 __anon90cc78240402() 79 std::function<bool(void)> undo2 = []() { return true; }; __anon90cc78240502() 80 std::function<bool(void)> redo2 = []() { return true; }; 81 REQUIRE(timeline->requestClipTimeWarp(cid3, 1.2, false, true, undo2, redo2)); 82 83 REQUIRE(timeline->getClipSpeed(cid3) == 1.2); 84 REQUIRE(timeline->getClipPlaytime(cid3) == int(originalDuration / 1.2)); 85 86 undo2(); 87 REQUIRE(timeline->getClipSpeed(cid3) == 0.1); 88 REQUIRE(timeline->getClipPlaytime(cid3) == originalDuration / 0.1); 89 90 undo(); 91 REQUIRE(timeline->getClipSpeed(cid3) == 1.); 92 REQUIRE(timeline->getClipPlaytime(cid3) == originalDuration); 93 94 // Finally, we test that setting a very high speed isn't possible. 95 // Specifically, it must be impossible to make the clip shorter than one frame 96 int curLength = timeline->getClipPlaytime(cid3); 97 98 // This is the limit, should work 99 REQUIRE(timeline->requestClipTimeWarp(cid3, double(curLength), false, true, undo2, redo2)); 100 101 REQUIRE(timeline->getClipSpeed(cid3) == double(curLength)); 102 REQUIRE(timeline->getClipPlaytime(cid3) == 1); 103 104 // This is the higher than the limit, should not work 105 // (we have some error margin in duration rounding, multiply by 10) 106 REQUIRE_FALSE(timeline->requestClipTimeWarp(cid3, double(curLength) * 10, false, true, undo2, redo2)); 107 } 108 binModel->clean(); 109 pCore->m_projectManager = nullptr; 110 } 111