~timo-jyrinki/ubuntu/trusty/pitivi/backport_utopic_fixes

« back to all changes in this revision

Viewing changes to tests/test_projectmanager.py

  • Committer: Package Import Robot
  • Author(s): Sebastian Dröge
  • Date: 2014-04-05 15:28:16 UTC
  • mfrom: (6.1.13 sid)
  • Revision ID: package-import@ubuntu.com-20140405152816-6lijoax4cngiz5j5
Tags: 0.93-3
* debian/control:
  + Depend on python-gi (>= 3.10), older versions do not work
    with pitivi (Closes: #732813).
  + Add missing dependency on gir1.2-clutter-gst-2.0 (Closes: #743692).
  + Add suggests on gir1.2-notify-0.7 and gir1.2-gnomedesktop-3.0.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# PiTiVi , Non-linear video editor
2
 
#
3
 
#       tests/test_projectmanager.py
4
 
#
5
 
# Copyright (c) 2009, Alessandro Decina <alessandro.d@gmail.com>
6
 
#
7
 
# This program is free software; you can redistribute it and/or
8
 
# modify it under the terms of the GNU Lesser General Public
9
 
# License as published by the Free Software Foundation; either
10
 
# version 2.1 of the License, or (at your option) any later version.
11
 
#
12
 
# This program is distributed in the hope that it will be useful,
13
 
# but WITHOUT ANY WARRANTY; without even the implied warranty of
14
 
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15
 
# Lesser General Public License for more details.
16
 
#
17
 
# You should have received a copy of the GNU Lesser General Public
18
 
# License along with this program; if not, write to the
19
 
# Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
20
 
# Boston, MA 02110-1301, USA.
21
 
 
22
 
from unittest import TestCase
23
 
 
24
 
from pitivi.projectmanager import ProjectManager
25
 
from pitivi.formatters.base import Formatter, \
26
 
        FormatterError, FormatterLoadError
27
 
import os
28
 
import gst
29
 
from pitivi.utils import uri_is_reachable
30
 
import time
31
 
 
32
 
 
33
 
class MockProject(object):
34
 
    settings = None
35
 
    format = None
36
 
    uri = None
37
 
    has_mods = True
38
 
 
39
 
    def hasUnsavedModifications(self):
40
 
        return self.has_mods
41
 
 
42
 
    def release(self):
43
 
        pass
44
 
 
45
 
    def disconnect_by_function(self, ignored):
46
 
        pass
47
 
 
48
 
 
49
 
class ProjectManagerListener(object):
50
 
    def __init__(self, manager):
51
 
        self.manager = manager
52
 
        self.connectToProjectManager(self.manager)
53
 
        self._reset()
54
 
 
55
 
    def _reset(self):
56
 
        self.signals = []
57
 
 
58
 
    def connectToProjectManager(self, manager):
59
 
        for signal in ("new-project-loading", "new-project-loaded",
60
 
                "new-project-created", "new-project-failed", "missing-uri",
61
 
                "closing-project", "project-closed"):
62
 
            self.manager.connect(signal, self._recordSignal, signal)
63
 
 
64
 
    def _recordSignal(self, *args):
65
 
        signal = args[-1]
66
 
        args = args[1:-1]
67
 
        self.signals.append((signal, args))
68
 
 
69
 
        return True
70
 
 
71
 
 
72
 
class TestProjectManager(TestCase):
73
 
    def setUp(self):
74
 
        self.manager = ProjectManager()
75
 
        self.listener = ProjectManagerListener(self.manager)
76
 
        self.signals = self.listener.signals
77
 
 
78
 
    def testLoadProjectFailedUnknownFormat(self):
79
 
        """
80
 
        Check that new-project-failed is emitted when we don't have a suitable
81
 
        formatter.
82
 
        """
83
 
        uri = "file:///Untitled.meh"
84
 
        self.manager.loadProject(uri)
85
 
        self.failUnlessEqual(len(self.signals), 2)
86
 
 
87
 
        # loading
88
 
        name, args = self.signals[0]
89
 
        self.failUnlessEqual(args[0], uri)
90
 
 
91
 
        # failed
92
 
        name, args = self.signals[1]
93
 
        self.failUnlessEqual(name, "new-project-failed")
94
 
        signalUri, exception = args
95
 
        self.failUnlessEqual(uri, signalUri)
96
 
        self.failUnless(isinstance(exception, FormatterLoadError))
97
 
 
98
 
    def testLoadProjectFailedCloseCurrent(self):
99
 
        """
100
 
        Check that new-project-failed is emited if we can't close the current
101
 
        project instance.
102
 
        """
103
 
        state = {"tried-close": False}
104
 
 
105
 
        def close():
106
 
            state["tried-close"] = True
107
 
            return False
108
 
        self.manager.closeRunningProject = close
109
 
 
110
 
        uri = "file:///Untitled.xptv"
111
 
        self.manager.loadProject(uri)
112
 
        self.failUnlessEqual(len(self.signals), 2)
113
 
 
114
 
        # loading
115
 
        name, args = self.signals[0]
116
 
        self.failUnlessEqual(args[0], uri)
117
 
 
118
 
        # failed
119
 
        name, args = self.signals[1]
120
 
        self.failUnlessEqual(name, "new-project-failed")
121
 
        signalUri, exception = args
122
 
        self.failUnlessEqual(uri, signalUri)
123
 
        self.failUnless(isinstance(exception, FormatterLoadError))
124
 
        self.failUnless(state["tried-close"])
125
 
 
126
 
    def testLoadProjectFailedProxyFormatter(self):
127
 
        """
128
 
        Check that new-project-failed is proxied when a formatter emits it.
129
 
        """
130
 
        class FailFormatter(Formatter):
131
 
            def _validateUri(self, uri):
132
 
                pass
133
 
 
134
 
            def _loadProject(self, location, project=None):
135
 
                raise FormatterError()
136
 
        self.manager._getFormatterForUri = lambda uri: FailFormatter([])
137
 
 
138
 
        uri = "file:///Untitled.xptv"
139
 
        self.manager.loadProject(uri)
140
 
        self.failUnlessEqual(len(self.signals), 3)
141
 
 
142
 
        # loading
143
 
        name, args = self.signals[0]
144
 
        self.failUnlessEqual(name, "new-project-loading")
145
 
        self.failUnlessEqual(args[0], uri)
146
 
 
147
 
        # created
148
 
        name, args = self.signals[1]
149
 
        self.failUnlessEqual(name, "new-project-created")
150
 
 
151
 
        # failed
152
 
        name, args = self.signals[2]
153
 
        self.failUnlessEqual(name, "new-project-failed")
154
 
        signalUri, exception = args
155
 
        self.failUnlessEqual(uri, signalUri)
156
 
        self.failUnless(isinstance(exception, FormatterError))
157
 
 
158
 
    def testLoadProjectMissingUri(self):
159
 
        class MissingUriFormatter(Formatter):
160
 
            def _validateUri(self, uri):
161
 
                pass
162
 
 
163
 
            def _loadProject(self, location, project):
164
 
                self._finishLoadingProject(project)
165
 
 
166
 
            def _getSources(self):
167
 
                # this will emit missing-uri
168
 
                self.validateSourceURI("file:///icantpossiblyexist", None)
169
 
                return []
170
 
 
171
 
            def _fillTimeline(self):
172
 
                pass
173
 
        self.manager._getFormatterForUri = lambda uri: MissingUriFormatter([])
174
 
 
175
 
        uri = "file:///Untitled.xptv"
176
 
        self.manager.loadProject(uri)
177
 
        self.failUnlessEqual(len(self.signals), 4)
178
 
 
179
 
        # loading
180
 
        name, args = self.signals[0]
181
 
        self.failUnlessEqual(name, "new-project-loading")
182
 
        self.failUnlessEqual(args[0], uri)
183
 
 
184
 
        name, args = self.signals[1]
185
 
        self.failUnlessEqual(name, "new-project-created")
186
 
        self.failUnlessEqual(args[0].uri, uri)
187
 
 
188
 
        # failed
189
 
        name, args = self.signals[2]
190
 
        self.failUnlessEqual(name, "missing-uri")
191
 
        formatter, signalUri, unused_factory = args
192
 
        self.failUnlessEqual(signalUri, "file:///icantpossiblyexist")
193
 
 
194
 
    def testLoadProjectLoaded(self):
195
 
        class EmptyFormatter(Formatter):
196
 
            def _validateUri(self, uri):
197
 
                pass
198
 
 
199
 
            def _loadProject(self, location, project):
200
 
                self._finishLoadingProject(project)
201
 
 
202
 
            def _getSources(self):
203
 
                return []
204
 
 
205
 
            def _fillTimeline(self):
206
 
                pass
207
 
        self.manager._getFormatterForUri = lambda uri: EmptyFormatter([])
208
 
 
209
 
        uri = "file:///Untitled.xptv"
210
 
        self.manager.loadProject(uri)
211
 
        self.failUnlessEqual(len(self.signals), 3)
212
 
 
213
 
        # loading
214
 
        name, args = self.signals[0]
215
 
        self.failUnlessEqual(args[0], uri)
216
 
 
217
 
        name, args = self.signals[1]
218
 
        self.failUnlessEqual(name, "new-project-created")
219
 
        project = args[0]
220
 
        self.failUnlessEqual(uri, project.uri)
221
 
 
222
 
        name, args = self.signals[2]
223
 
        self.failUnlessEqual(name, "new-project-loaded")
224
 
        project = args[0]
225
 
        self.failUnlessEqual(uri, project.uri)
226
 
 
227
 
    def testCloseRunningProjectNoProject(self):
228
 
        self.failUnless(self.manager.closeRunningProject())
229
 
        self.failIf(self.signals)
230
 
 
231
 
    def testCloseRunningProjectRefuseFromSignal(self):
232
 
        def closing(manager, project):
233
 
            return False
234
 
 
235
 
        self.manager.current = MockProject()
236
 
        self.manager.current.has_mods = False
237
 
        self.manager.current.uri = "file:///ciao"
238
 
        self.manager.connect("closing-project", closing)
239
 
 
240
 
        self.failIf(self.manager.closeRunningProject())
241
 
        self.failUnlessEqual(len(self.signals), 1)
242
 
        name, args = self.signals[0]
243
 
        self.failUnlessEqual(name, "closing-project")
244
 
        project = args[0]
245
 
        self.failUnless(project is self.manager.current)
246
 
 
247
 
    def testCloseRunningProject(self):
248
 
        current = self.manager.current = MockProject()
249
 
        self.manager.current.has_mods = False
250
 
        self.failUnless(self.manager.closeRunningProject())
251
 
        self.failUnlessEqual(len(self.signals), 2)
252
 
 
253
 
        name, args = self.signals[0]
254
 
        self.failUnlessEqual(name, "closing-project")
255
 
        project = args[0]
256
 
        self.failUnless(project is current)
257
 
 
258
 
        name, args = self.signals[1]
259
 
        self.failUnlessEqual(name, "project-closed")
260
 
        project = args[0]
261
 
        self.failUnless(project is current)
262
 
 
263
 
        self.failUnlessEqual(self.manager.current, None)
264
 
 
265
 
    def testNewBlankProjectCantCloseCurrent(self):
266
 
        def closing(manager, project):
267
 
            return False
268
 
 
269
 
        self.manager.current = MockProject()
270
 
        self.manager.current.has_mods = False
271
 
        self.manager.current.uri = "file:///ciao"
272
 
        self.manager.connect("closing-project", closing)
273
 
        self.failIf(self.manager.newBlankProject())
274
 
        self.failUnlessEqual(len(self.signals), 1)
275
 
        signal, args = self.signals[0]
276
 
        self.failUnlessEqual(signal, "closing-project")
277
 
 
278
 
    def testNewBlankProject(self):
279
 
        self.failUnless(self.manager.newBlankProject())
280
 
        self.failUnlessEqual(len(self.signals), 3)
281
 
 
282
 
        name, args = self.signals[0]
283
 
        self.failUnlessEqual(name, "new-project-loading")
284
 
        uri = args[0]
285
 
        self.failUnlessEqual(uri, None)
286
 
 
287
 
        name, args = self.signals[1]
288
 
        self.failUnlessEqual(name, "new-project-created")
289
 
        project = args[0]
290
 
        self.failUnlessEqual(uri, project.uri)
291
 
 
292
 
        name, args = self.signals[2]
293
 
        self.failUnlessEqual(name, "new-project-loaded")
294
 
        project = args[0]
295
 
        self.failUnless(project is self.manager.current)
296
 
 
297
 
    def testSaveProject(self):
298
 
        uri = "file://" + os.path.abspath("testproject.xptv")
299
 
        uri2 = "file://" + os.path.abspath("testproject2.xptv")
300
 
        path = gst.uri_get_location(uri)
301
 
        path2 = gst.uri_get_location(uri2)
302
 
 
303
 
        # unlink any existing project files
304
 
        try:
305
 
            os.unlink(path)
306
 
            os.unlink(path2)
307
 
        except OSError:
308
 
            pass
309
 
 
310
 
        # save a project
311
 
        self.failUnless(self.manager.newBlankProject())
312
 
        self.failUnless(self.manager.saveProject(
313
 
            self.manager.current, uri, True))
314
 
        self.failUnless(uri_is_reachable(uri))
315
 
 
316
 
        # wait a bit
317
 
        time.sleep(1.0)
318
 
 
319
 
        # save project under new path
320
 
        self.failUnless(self.manager.saveProject(
321
 
            self.manager.current, uri2, True))
322
 
        self.failUnless(uri_is_reachable(uri2))
323
 
 
324
 
        # make sure the old path and the new path have different mtime
325
 
        mtime = os.path.getmtime(path)
326
 
        mtime2 = os.path.getmtime(path2)
327
 
        self.failUnless(mtime < mtime2)
328
 
 
329
 
        # wait a bit more
330
 
        time.sleep(1.0)
331
 
 
332
 
        # save project again under new path (by omitting uri arg)
333
 
        self.failUnless(self.manager.saveProject(
334
 
            self.manager.current, overwrite=True))
335
 
 
336
 
        # regression test for bug 594396
337
 
        # make sure we didn't save to the old URI
338
 
        self.failUnlessEqual(mtime, os.path.getmtime(path))
339
 
        # make sure we did save to the new URI
340
 
        self.failUnless(mtime2 < os.path.getmtime(path2))
341
 
 
342
 
        # unlink any existing project files
343
 
        try:
344
 
            os.unlink(path)
345
 
            os.unlink(path2)
346
 
        except OSError:
347
 
            pass
348
 
 
349
 
    def testBackupProject(self):
350
 
        uri = "file://" + os.path.abspath("testproject.xptv")
351
 
 
352
 
        # Create and save the project
353
 
        self.manager.newBlankProject()
354
 
        self.manager.saveProject(self.manager.current, uri, True)
355
 
 
356
 
        # Save the backup
357
 
        self.manager._saveBackupCb(self.manager.current, uri)
358
 
        backup_uri = self.manager._makeBackupURI(uri)
359
 
        self.failUnless(uri_is_reachable(uri))
360
 
        self.failUnless(uri_is_reachable(backup_uri))
361
 
 
362
 
        # When closing it should clean the backup
363
 
        self.manager.closeRunningProject()
364
 
        self.failUnless(not uri_is_reachable(backup_uri))
365
 
 
366
 
        # unlink any existing project files
367
 
        try:
368
 
            os.unlink(uri)
369
 
            os.unlink(backup_uri)
370
 
        except OSError:
371
 
            pass