[pitivi] Add tests for undoing/redoing timeline actions. Fix redoing split.



commit 5632f1217105f679f81b59dee08924441cb93440
Author: Alessandro Decina <alessandro d gmail com>
Date:   Thu Jun 11 12:07:14 2009 +0200

    Add tests for undoing/redoing timeline actions. Fix redoing split.

 pitivi/timeline/timeline_undo.py |   17 ++-
 tests/test_timeline_undo.py      |  187 ++++++++++++++++++++++++++++++++++++++
 2 files changed, 198 insertions(+), 6 deletions(-)
---
diff --git a/pitivi/timeline/timeline_undo.py b/pitivi/timeline/timeline_undo.py
index 397caac..4be64e8 100644
--- a/pitivi/timeline/timeline_undo.py
+++ b/pitivi/timeline/timeline_undo.py
@@ -52,17 +52,18 @@ class TimelineObjectAdded(UndoableAction):
     def do(self):
         temporary_timeline_object = \
                 self._copyTimelineObject(self.timeline_object_copy)
+        self.timeline_object.track_objects = []
         for track_object in temporary_timeline_object.track_objects:
             track, track_object.track = track_object.track, None
             track.addTrackObject(track_object)
+            self.timeline_object.addTrackObject(track_object)
 
-        self.timeline_object.track_objects = temporary_timeline_object.track_objects
         self.timeline.addTimelineObject(self.timeline_object)
-        self._undone()
+        self._done()
 
     def undo(self):
         self.timeline.removeTimelineObject(self.timeline_object, deep=True)
-        self._done()
+        self._undone()
 
     def _copyTimelineObject(self, timeline_object):
         copy = timeline_object.copy()
@@ -102,6 +103,10 @@ class TimelineObjectRemoved(UndoableAction):
         return copy
 
 class TimelineLogObserver(object):
+    propertyChangedAction = TimelineObjectPropertyChanged
+    timelineObjectAddedAction = TimelineObjectAdded
+    timelineObjectRemovedAction = TimelineObjectRemoved
+
     def __init__(self, log):
         self.log = log
         self.property_trackers = {}
@@ -139,16 +144,16 @@ class TimelineLogObserver(object):
 
     def _timelineObjectAddedCb(self, timeline, timeline_object):
         self._connectToTimelineObject(timeline_object)
-        action = TimelineObjectAdded(timeline, timeline_object)
+        action = self.timelineObjectAddedAction(timeline, timeline_object)
         self.log.push(action)
 
     def _timelineObjectRemovedCb(self, timeline, timeline_object):
         self._disconnectFromTimelineObject(timeline_object)
-        action = TimelineObjectRemoved(timeline, timeline_object)
+        action = self.timelineObjectRemovedAction(timeline, timeline_object)
         self.log.push(action)
 
     def _timelineObjectPropertyChangedCb(self, tracker, timeline_object,
             old_value, new_value, property_name):
-        action = TimelineObjectPropertyChanged(timeline_object,
+        action = self.propertyChangedAction(timeline_object,
                 property_name, old_value, new_value)
         self.log.push(action)
diff --git a/tests/test_timeline_undo.py b/tests/test_timeline_undo.py
new file mode 100644
index 0000000..6eef513
--- /dev/null
+++ b/tests/test_timeline_undo.py
@@ -0,0 +1,187 @@
+# PiTiVi , Non-linear video editor
+#
+#       tests/test_timeline_undo.py
+#
+# Copyright (c) 2009, Alessandro Decina <alessandro d gmail com>
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this program; if not, write to the
+# Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+# Boston, MA 02111-1307, USA.
+
+from unittest import TestCase
+
+import gobject
+gobject.threads_init()
+import gst
+
+from pitivi.timeline.timeline import Timeline, TimelineObject
+from pitivi.timeline.track import Track, SourceTrackObject
+from pitivi.factories.test import VideoTestSourceFactory
+from pitivi.stream import VideoStream
+from pitivi.timeline.timeline_undo import TimelineLogObserver, \
+        TimelineObjectAdded, TimelineObjectRemoved, \
+        TimelineObjectPropertyChanged
+from pitivi.undo import UndoableActionLog
+
+class TestTimelineLogObserver(TimelineLogObserver):
+    def _connectToTimeline(self, timeline):
+        TimelineLogObserver._connectToTimeline(self, timeline)
+        timeline.connected = True
+
+    def _disconnectFromTimeline(self, timeline):
+        TimelineLogObserver._disconnectFromTimeline(self, timeline)
+        timeline.connected = False
+
+    def _connectToTimelineObject(self, timeline_object):
+        TimelineLogObserver._connectToTimelineObject(self, timeline_object)
+        timeline_object.connected = True
+    
+    def _disconnectFromTimelineObject(self, timeline_object):
+        TimelineLogObserver._disconnectFromTimelineObject(self, timeline_object)
+        timeline_object.connected = False
+
+def new_stream():
+    return VideoStream(gst.Caps("video/x-raw-rgb"))
+
+def new_factory():
+    return VideoTestSourceFactory()
+
+class TestTimelineLogObserverConnections(TestCase):
+    def setUp(self):
+        self.action_log = UndoableActionLog()
+        self.observer = TestTimelineLogObserver(self.action_log)
+
+    def testConnectionAndDisconnection(self):
+        timeline = Timeline()
+        stream = new_stream()
+        factory = new_factory()
+        track = Track(stream)
+        track_object1 = SourceTrackObject(factory, stream)
+        track.addTrackObject(track_object1)
+        timeline.addTrack(track)
+        timeline_object1 = TimelineObject(factory)
+        timeline_object1.addTrackObject(track_object1)
+        timeline.addTimelineObject(timeline_object1)
+
+        self.observer.startObserving(timeline)
+        self.failUnless(timeline.connected)
+        self.failUnless(timeline_object1.connected)
+
+        timeline.removeTimelineObject(timeline_object1)
+        self.failIf(timeline_object1.connected)
+
+        timeline.addTimelineObject(timeline_object1)
+        self.failUnless(timeline_object1)
+
+        self.observer.stopObserving(timeline)
+        self.failIf(timeline.connected)
+        self.failIf(timeline_object1.connected)
+
+class  TestTimelineUndo(TestCase):
+    def setUp(self):
+        self.stream = new_stream()
+        self.factory = new_factory()
+        self.track1 = Track(self.stream)
+        self.track2 = Track(self.stream)
+        self.timeline = Timeline()
+        self.timeline.addTrack(self.track1)
+        self.timeline.addTrack(self.track2)
+        self.track_object1 = SourceTrackObject(self.factory, self.stream)
+        self.track_object2 = SourceTrackObject(self.factory, self.stream)
+        self.track1.addTrackObject(self.track_object1)
+        self.track2.addTrackObject(self.track_object2)
+        self.timeline_object1 = TimelineObject(self.factory)
+        self.timeline_object1.addTrackObject(self.track_object1)
+        self.timeline_object1.addTrackObject(self.track_object2)
+        self.action_log = UndoableActionLog()
+        self.observer = TestTimelineLogObserver(self.action_log)
+        self.observer.startObserving(self.timeline)
+
+    def testAddTimelineObject(self):
+        stacks = []
+        def commitCb(action_log, stack, nested):
+            stacks.append(stack)
+        self.action_log.connect("commit", commitCb)
+
+        self.action_log.begin("add clip")
+        self.timeline.addTimelineObject(self.timeline_object1)
+        self.action_log.commit()
+
+        self.failUnlessEqual(len(stacks), 1)
+        stack = stacks[0]
+        self.failUnlessEqual(len(stack.done_actions), 1)
+        action = stack.done_actions[0]
+        self.failUnless(isinstance(action, TimelineObjectAdded))
+
+        self.failUnless(self.timeline_object1 \
+                in self.timeline.timeline_objects)
+        self.action_log.undo()
+        self.failIf(self.timeline_object1 \
+                in self.timeline.timeline_objects)
+
+        self.action_log.redo()
+        self.failUnless(self.timeline_object1 \
+                in self.timeline.timeline_objects)
+
+    def testRemoveTimelineObject(self):
+        stacks = []
+        def commitCb(action_log, stack, nested):
+            stacks.append(stack)
+        self.action_log.connect("commit", commitCb)
+
+        self.timeline.addTimelineObject(self.timeline_object1)
+        self.action_log.begin("remove clip")
+        self.timeline.removeTimelineObject(self.timeline_object1)
+        self.action_log.commit()
+
+        self.failUnlessEqual(len(stacks), 1)
+        stack = stacks[0]
+        self.failUnlessEqual(len(stack.done_actions), 1)
+        action = stack.done_actions[0]
+        self.failUnless(isinstance(action, TimelineObjectRemoved))
+
+        self.failIf(self.timeline_object1 \
+                in self.timeline.timeline_objects)
+        self.action_log.undo()
+        self.failUnless(self.timeline_object1 \
+                in self.timeline.timeline_objects)
+
+        self.action_log.redo()
+        self.failIf(self.timeline_object1 \
+                in self.timeline.timeline_objects)
+
+    def testTimelineObjectPropertyChange(self):
+        stacks = []
+        def commitCb(action_log, stack, nested):
+            stacks.append(stack)
+        self.action_log.connect("commit", commitCb)
+
+        self.timeline_object1.start = 5 * gst.SECOND
+        self.timeline_object1.duration = 20 * gst.SECOND
+        self.timeline.addTimelineObject(self.timeline_object1)
+        self.action_log.begin("modify clip")
+        self.timeline_object1.start = 10 * gst.SECOND
+        self.action_log.commit()
+
+        self.failUnlessEqual(len(stacks), 1)
+        stack = stacks[0]
+        self.failUnlessEqual(len(stack.done_actions), 1)
+        action = stack.done_actions[0]
+        self.failUnless(isinstance(action, TimelineObjectPropertyChanged))
+
+        self.failUnlessEqual(self.timeline_object1.start, 10 * gst.SECOND)
+        self.action_log.undo()
+        self.failUnlessEqual(self.timeline_object1.start, 5 * gst.SECOND)
+        self.action_log.redo()
+        self.failUnlessEqual(self.timeline_object1.start, 10 * gst.SECOND)



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]