16
16
along with this program. If not, see <http://www.gnu.org/licenses/>.
21
from unittests import dummy
22
19
from taskcoachlib import gui, config, persistence
23
20
from taskcoachlib.domain import task, note, category
24
21
from taskcoachlib.thirdparty import lockfile
22
from unittests import dummy
27
29
class IOControllerTest(test.TestCase):
40
42
if os.path.exists(filename):
41
43
os.remove(filename)
42
44
if os.path.exists(filename + '.lock'):
43
shutil.rmtree(filename + '.lock') # pragma: no cover
45
shutil.rmtree(filename + '.lock') # pragma: no cover
44
46
if os.path.exists(filename + '.delta'):
45
47
os.remove(filename + '.delta')
46
48
super(IOControllerTest, self).tearDown()
48
def doIOAndCheckRecentFiles(self, open=None, saveas=None, # pylint: disable=W0622
50
def doIOAndCheckRecentFiles(self, open=None, saveas=None, # pylint: disable=W0622
49
51
saveselection=None, merge=None, expectedFilenames=None):
51
53
saveas = saveas or []
53
55
merge = merge or []
54
56
self.doIO(open, saveas, saveselection, merge)
55
57
self.checkRecentFiles(expectedFilenames or \
56
open+saveas+saveselection+merge)
58
open + saveas + saveselection + merge)
58
def doIO(self, open, saveas, saveselection, merge): # pylint: disable=W0622
60
def doIO(self, open, saveas, saveselection, merge): # pylint: disable=W0622
59
61
for filename in open:
60
62
self.iocontroller.open(filename, fileExists=lambda filename: True)
61
63
for filename in saveas:
78
80
self.doIOAndCheckRecentFiles(open=[self.filename1, self.filename2])
80
82
def testOpenTheSameFileTwiceAddsItToRecentFilesOnce(self):
81
self.doIOAndCheckRecentFiles(open=[self.filename1]*2,
83
self.doIOAndCheckRecentFiles(open=[self.filename1] * 2,
82
84
expectedFilenames=[self.filename1])
84
86
def testSaveFileAsAddsItToRecentFiles(self):
94
96
def testMaximumNumberOfRecentFiles(self):
95
97
maximumNumberOfRecentFiles = self.settings.getint('file',
97
filenames = ['filename %d'%index for index in \
98
range(maximumNumberOfRecentFiles+1)]
99
filenames = ['filename %d' % index for index in \
100
range(maximumNumberOfRecentFiles + 1)]
99
101
self.doIOAndCheckRecentFiles(filenames,
100
102
expectedFilenames=filenames[1:])
102
104
def testSaveTaskFileWithoutTasksButWithNotes(self):
103
105
self.taskFile.notes().append(note.Note(subject='Note'))
104
def saveasReplacement(*args, **kwargs): # pylint: disable=W0613
105
self.saveAsCalled = True # pylint: disable=W0201
107
def saveasReplacement(*args, **kwargs): # pylint: disable=W0613
108
self.saveAsCalled = True # pylint: disable=W0201
106
110
originalSaveAs = self.iocontroller.__class__.saveas
107
111
self.iocontroller.__class__.saveas = saveasReplacement
108
112
self.iocontroller.save()
112
116
def testIOErrorOnSave(self):
113
117
self.taskFile.setFilename(self.filename1)
114
def saveasReplacement(*args, **kwargs): # pylint: disable=W0613
119
def saveasReplacement(*args, **kwargs): # pylint: disable=W0613
115
120
self.saveAsCalled = True
116
122
originalSaveAs = self.iocontroller.__class__.saveas
117
123
self.iocontroller.__class__.saveas = saveasReplacement
118
124
self.taskFile.raiseError = IOError
119
def showerror(*args, **kwargs): # pylint: disable=W0613
120
self.showerrorCalled = True # pylint: disable=W0201
126
def showerror(*args, **kwargs): # pylint: disable=W0613
127
self.showerrorCalled = True # pylint: disable=W0201
121
129
self.iocontroller.save(showerror=showerror)
122
130
self.failUnless(self.showerrorCalled and self.saveAsCalled)
123
131
self.iocontroller.__class__.saveas = originalSaveAs
125
133
def testIOErrorOnSaveAs(self):
126
134
self.taskFile.raiseError = IOError
127
def saveasReplacement(*args, **kwargs): # pylint: disable=W0613
136
def saveasReplacement(*args, **kwargs): # pylint: disable=W0613
128
137
self.saveAsCalled = True
129
139
originalSaveAs = self.iocontroller.__class__.saveas
130
def showerror(*args, **kwargs): # pylint: disable=W0613
141
def showerror(*args, **kwargs): # pylint: disable=W0613
131
142
self.showerrorCalled = True
132
143
# Prevent the recursive call of saveas:
133
144
self.iocontroller.__class__.saveas = saveasReplacement
134
146
self.iocontroller.saveas(filename=self.filename1, showerror=showerror)
135
147
self.failUnless(self.showerrorCalled and self.saveAsCalled)
136
148
self.iocontroller.__class__.saveas = originalSaveAs
170
def testSaveSelectionAddsParentCategoriesWhenSubcategoriesAreUsed(self):
172
self.taskFile.tasks().extend([task1])
173
aCategory = category.Category('A category')
174
aSubCategory = category.Category('A subcategory')
175
aCategory.addChild(aSubCategory)
176
self.taskFile.categories().append(aCategory)
177
task1.addCategory(aSubCategory)
178
aSubCategory.addCategorizable(task1)
179
self.iocontroller.saveselection(tasks=self.taskFile.tasks(),
180
filename=self.filename1)
181
taskFile = persistence.TaskFile()
182
taskFile.setFilename(self.filename1)
184
self.assertEqual(2, len(taskFile.categories()))
158
186
def testIOErrorOnSaveSave(self):
159
187
self.taskFile.raiseError = IOError
160
188
self.taskFile.setFilename(self.filename1)
161
def showerror(*args, **kwargs): # pylint: disable=W0613
190
def showerror(*args, **kwargs): # pylint: disable=W0613
162
191
self.showerrorCalled = True
163
193
self.taskFile.tasks().append(task.Task())
164
self.iocontroller._saveSave(self.taskFile, showerror) # pylint: disable=W0212
194
self.iocontroller._saveSave(self.taskFile, showerror) # pylint: disable=W0212
165
195
self.failUnless(self.showerrorCalled)
167
197
def testIOErrorOnExport(self):
168
198
self.taskFile.setFilename(self.filename1)
169
199
self.taskFile.tasks().append(task.Task())
170
def showerror(*args, **kwargs): # pylint: disable=W0613
201
def showerror(*args, **kwargs): # pylint: disable=W0613
171
202
self.showerrorCalled = True
172
def openfile(*args, **kwargs):
204
def openfile(*args, **kwargs): # pylint: disable=W0613
174
207
self.iocontroller.exportAsHTML(None, filename="Don't ask",
175
208
openfile=openfile, showerror=showerror)
176
209
self.failUnless(self.showerrorCalled)
244
277
def testOpenWhenLockFailed(self):
245
278
self.taskFile.raiseError = lockfile.LockFailed
246
def askOpenUnlocked(*args, **kwargs): # pylint: disable=W0613
280
def askOpenUnlocked(*args, **kwargs): # pylint: disable=W0613
247
281
self.askOpenUnlockedCalled = True
248
283
self.iocontroller._IOController__askOpenUnlocked = askOpenUnlocked
249
284
self.iocontroller.open(self.filename1, fileExists=lambda filename: True)
250
285
self.failUnless(self.askOpenUnlockedCalled)
252
287
def testOpenWhenAlreadyLocked(self):
253
288
self.taskFile.raiseError = lockfile.LockTimeout
254
290
def askBreakLock(*args, **kwargs): # pylint: disable=W0613
255
291
self.askBreakLockCalled = True
256
293
self.iocontroller._IOController__askBreakLock = askBreakLock
257
294
self.iocontroller.open(self.filename1, fileExists=lambda filename: True)
258
295
self.failUnless(self.askBreakLockCalled)
264
301
self.originalFileSelector = wx.FileSelector
265
302
wx.FileSelector = lambda *args, **kwargs: 'filename without extension to trigger our own overwrite warning'
266
303
self.originalMessageBox = wx.MessageBox
267
def messageBox(*args, **kwargs):
305
def messageBox(*args, **kwargs): # pylint: disable=W0613
268
306
self.userWarned = True
270
309
wx.MessageBox = messageBox
271
310
task.Task.settings = self.settings = config.Settings(load=False)
272
311
self.taskFile = dummy.TaskFile()
297
336
self.failUnless(self.userWarned)
299
338
def testCancelExportAsICalendarToExistingFile(self):
300
self.iocontroller.exportAsICalendar(None, fileExists=lambda filename: True)
339
self.iocontroller.exportAsICalendar(None,
340
fileExists=lambda filename: True)
301
341
self.failUnless(self.userWarned)