]> git.madduck.net Git - etc/taskwarrior.git/blob - tasklib/tests.py

madduck's git repository

Every one of the projects in this repository is available at the canonical URL git://git.madduck.net/madduck/pub/<projectpath> — see each project's metadata for the exact URL.

All patches and comments are welcome. Please squash your changes to logical commits before using git-format-patch and git-send-email to patches@git.madduck.net. If you'd read over the Git project's submission guidelines and adhered to them, I'd be especially grateful.

SSH access, as well as push access can be individually arranged.

If you use my repositories frequently, consider adding the following snippet to ~/.gitconfig and using the third clone URL listed for each project:

[url "git://git.madduck.net/madduck/"]
  insteadOf = madduck:

4d88436e1e7399583d54177ac43bec014212b3a5
[etc/taskwarrior.git] / tasklib / tests.py
1 # coding=utf-8
2
3 import datetime
4 import shutil
5 import tempfile
6 import unittest
7
8 from .task import TaskWarrior, Task
9
10
11 class TasklibTest(unittest.TestCase):
12
13     def setUp(self):
14         self.tmp = tempfile.mkdtemp(dir='.')
15         self.tw = TaskWarrior(data_location=self.tmp)
16
17     def tearDown(self):
18         shutil.rmtree(self.tmp)
19
20
21 class TaskFilterTest(TasklibTest):
22
23     def test_all_empty(self):
24         self.assertEqual(len(self.tw.tasks.all()), 0)
25
26     def test_all_non_empty(self):
27         Task(self.tw, description="test task").save()
28         self.assertEqual(len(self.tw.tasks.all()), 1)
29         self.assertEqual(self.tw.tasks.all()[0]['description'], 'test task')
30         self.assertEqual(self.tw.tasks.all()[0]['status'], 'pending')
31
32     def test_pending_non_empty(self):
33         Task(self.tw, description="test task").save()
34         self.assertEqual(len(self.tw.tasks.pending()), 1)
35         self.assertEqual(self.tw.tasks.pending()[0]['description'],
36                          'test task')
37         self.assertEqual(self.tw.tasks.pending()[0]['status'], 'pending')
38
39     def test_completed_empty(self):
40         Task(self.tw, description="test task").save()
41         self.assertEqual(len(self.tw.tasks.completed()), 0)
42
43     def test_completed_non_empty(self):
44         Task(self.tw, description="test task").save()
45         self.assertEqual(len(self.tw.tasks.completed()), 0)
46         self.tw.tasks.all()[0].done()
47         self.assertEqual(len(self.tw.tasks.completed()), 1)
48
49     def test_filtering_by_attribute(self):
50         Task(self.tw, description="no priority task").save()
51         Task(self.tw, priority="H", description="high priority task").save()
52         self.assertEqual(len(self.tw.tasks.all()), 2)
53
54         # Assert that the correct number of tasks is returned
55         self.assertEqual(len(self.tw.tasks.filter(priority="H")), 1)
56
57         # Assert that the correct tasks are returned
58         high_priority_task = self.tw.tasks.get(priority="H")
59         self.assertEqual(high_priority_task['description'], "high priority task")
60
61     def test_filtering_by_empty_attribute(self):
62         Task(self.tw, description="no priority task").save()
63         Task(self.tw, priority="H", description="high priority task").save()
64         self.assertEqual(len(self.tw.tasks.all()), 2)
65
66         # Assert that the correct number of tasks is returned
67         self.assertEqual(len(self.tw.tasks.filter(priority=None)), 1)
68
69         # Assert that the correct tasks are returned
70         no_priority_task = self.tw.tasks.get(priority=None)
71         self.assertEqual(no_priority_task['description'], "no priority task")
72
73
74 class TaskTest(TasklibTest):
75
76     def test_create_unsaved_task(self):
77         # Make sure a new task is not saved unless explicitly called for
78         t = Task(self.tw, description="test task")
79         self.assertEqual(len(self.tw.tasks.all()), 0)
80
81     # TODO: once python 2.6 compatiblity is over, use context managers here
82     #       and in all subsequent tests for assertRaises
83
84     def test_delete_unsaved_task(self):
85         t = Task(self.tw, description="test task")
86         self.assertRaises(Task.NotSaved, t.delete)
87
88     def test_complete_unsaved_task(self):
89         t = Task(self.tw, description="test task")
90         self.assertRaises(Task.NotSaved, t.done)
91
92     def test_refresh_unsaved_task(self):
93         t = Task(self.tw, description="test task")
94         self.assertRaises(Task.NotSaved, t.refresh)
95
96     def test_delete_deleted_task(self):
97         t = Task(self.tw, description="test task")
98         t.save()
99         t.delete()
100
101         self.assertRaises(Task.DeletedTask, t.delete)
102
103     def test_complete_completed_task(self):
104         t = Task(self.tw, description="test task")
105         t.save()
106         t.done()
107
108         self.assertRaises(Task.CompletedTask, t.done)
109
110     def test_complete_deleted_task(self):
111         t = Task(self.tw, description="test task")
112         t.save()
113         t.delete()
114
115         self.assertRaises(Task.DeletedTask, t.done)
116
117     def test_empty_dependency_set_of_unsaved_task(self):
118         t = Task(self.tw, description="test task")
119         self.assertEqual(t['depends'], set())
120
121     def test_empty_dependency_set_of_saved_task(self):
122         t = Task(self.tw, description="test task")
123         t.save()
124         self.assertEqual(t['depends'], set())
125
126     def test_set_unsaved_task_as_dependency(self):
127         # Adds only one dependency to task with no dependencies
128         t = Task(self.tw, description="test task")
129         dependency = Task(self.tw, description="needs to be done first")
130
131         # We only save the parent task, dependency task is unsaved
132         t.save()
133
134         self.assertRaises(Task.NotSaved,
135                           t.__setitem__, 'depends', set([dependency]))
136
137     def test_set_simple_dependency_set(self):
138         # Adds only one dependency to task with no dependencies
139         t = Task(self.tw, description="test task")
140         dependency = Task(self.tw, description="needs to be done first")
141
142         t.save()
143         dependency.save()
144
145         t['depends'] = set([dependency])
146
147         self.assertEqual(t['depends'], set([dependency]))
148
149     def test_set_complex_dependency_set(self):
150         # Adds two dependencies to task with no dependencies
151         t = Task(self.tw, description="test task")
152         dependency1 = Task(self.tw, description="needs to be done first")
153         dependency2 = Task(self.tw, description="needs to be done second")
154
155         t.save()
156         dependency1.save()
157         dependency2.save()
158
159         t['depends'] = set([dependency1, dependency2])
160
161         self.assertEqual(t['depends'], set([dependency1, dependency2]))
162
163     def test_remove_from_dependency_set(self):
164         # Removes dependency from task with two dependencies
165         t = Task(self.tw, description="test task")
166         dependency1 = Task(self.tw, description="needs to be done first")
167         dependency2 = Task(self.tw, description="needs to be done second")
168
169         dependency1.save()
170         dependency2.save()
171
172         t['depends'] = set([dependency1, dependency2])
173         t.save()
174
175         t['depends'] = t['depends'] - set([dependency2])
176         t.save()
177
178         self.assertEqual(t['depends'], set([dependency1]))
179
180     def test_add_to_dependency_set(self):
181         # Adds dependency to task with one dependencies
182         t = Task(self.tw, description="test task")
183         dependency1 = Task(self.tw, description="needs to be done first")
184         dependency2 = Task(self.tw, description="needs to be done second")
185
186         dependency1.save()
187         dependency2.save()
188
189         t['depends'] = set([dependency1])
190         t.save()
191
192         t['depends'] = t['depends'] | set([dependency2])
193         t.save()
194
195         self.assertEqual(t['depends'], set([dependency1, dependency2]))
196
197     def test_simple_dependency_set_save_repeatedly(self):
198         # Adds only one dependency to task with no dependencies
199         t = Task(self.tw, description="test task")
200         dependency = Task(self.tw, description="needs to be done first")
201         dependency.save()
202
203         t['depends'] = set([dependency])
204         t.save()
205
206         # We taint the task, but keep depends intact
207         t['description'] = "test task modified"
208         t.save()
209
210         self.assertEqual(t['depends'], set([dependency]))
211
212         # We taint the task, but assign the same set to the depends
213         t['depends'] = set([dependency])
214         t['description'] = "test task modified again"
215         t.save()
216
217         self.assertEqual(t['depends'], set([dependency]))
218
219     def test_compare_different_tasks(self):
220         # Negative: compare two different tasks
221         t1 = Task(self.tw, description="test task")
222         t2 = Task(self.tw, description="test task")
223
224         t1.save()
225         t2.save()
226
227         self.assertEqual(t1 == t2, False)
228
229     def test_compare_same_task_object(self):
230         # Compare Task object wit itself
231         t = Task(self.tw, description="test task")
232         t.save()
233
234         self.assertEqual(t == t, True)
235
236     def test_compare_same_task(self):
237         # Compare the same task using two different objects
238         t1 = Task(self.tw, description="test task")
239         t1.save()
240
241         t2 = self.tw.tasks.get(uuid=t1['uuid'])
242         self.assertEqual(t1 == t2, True)
243
244     def test_compare_unsaved_tasks(self):
245         # t1 and t2 are unsaved tasks, considered to be unequal
246         # despite the content of data
247         t1 = Task(self.tw, description="test task")
248         t2 = Task(self.tw, description="test task")
249
250         self.assertEqual(t1 == t2, False)
251
252     def test_hash_unsaved_tasks(self):
253         # Considered equal, it's the same object
254         t1 = Task(self.tw, description="test task")
255         t2 = t1
256         self.assertEqual(hash(t1) == hash(t2), True)
257
258     def test_hash_same_task(self):
259         # Compare the hash of the task using two different objects
260         t1 = Task(self.tw, description="test task")
261         t1.save()
262
263         t2 = self.tw.tasks.get(uuid=t1['uuid'])
264         self.assertEqual(t1.__hash__(), t2.__hash__())
265
266     def test_adding_task_with_priority(self):
267         t = Task(self.tw, description="test task", priority="M")
268         t.save()
269
270     def test_removing_priority_with_none(self):
271         t = Task(self.tw, description="test task", priority="L")
272         t.save()
273
274         # Remove the priority mark
275         t['priority'] = None
276         t.save()
277
278         # Assert that priority is not there after saving
279         self.assertEqual(t['priority'], None)
280
281     def test_adding_task_with_due_time(self):
282         t = Task(self.tw, description="test task", due=datetime.datetime.now())
283         t.save()
284
285     def test_removing_due_time_with_none(self):
286         t = Task(self.tw, description="test task", due=datetime.datetime.now())
287         t.save()
288
289         # Remove the due timestamp
290         t['due'] = None
291         t.save()
292
293         # Assert that due timestamp is no longer there
294         self.assertEqual(t['due'], None)
295
296
297 class AnnotationTest(TasklibTest):
298
299     def setUp(self):
300         super(AnnotationTest, self).setUp()
301         Task(self.tw, description="test task").save()
302
303     def test_adding_annotation(self):
304         task = self.tw.tasks.get()
305         task.add_annotation('test annotation')
306         self.assertEqual(len(task['annotations']), 1)
307         ann = task['annotations'][0]
308         self.assertEqual(ann['description'], 'test annotation')
309
310     def test_removing_annotation(self):
311         task = self.tw.tasks.get()
312         task.add_annotation('test annotation')
313         ann = task['annotations'][0]
314         ann.remove()
315         self.assertEqual(len(task['annotations']), 0)
316
317     def test_removing_annotation_by_description(self):
318         task = self.tw.tasks.get()
319         task.add_annotation('test annotation')
320         task.remove_annotation('test annotation')
321         self.assertEqual(len(task['annotations']), 0)
322
323     def test_removing_annotation_by_obj(self):
324         task = self.tw.tasks.get()
325         task.add_annotation('test annotation')
326         ann = task['annotations'][0]
327         task.remove_annotation(ann)
328         self.assertEqual(len(task['annotations']), 0)
329
330
331 class UnicodeTest(TasklibTest):
332
333     def test_unicode_task(self):
334         Task(self.tw, description="†åßk").save()
335         self.tw.tasks.get()
336
337     def test_non_unicode_task(self):
338         Task(self.tw, description="test task").save()
339         self.tw.tasks.get()