]> 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:

Tests: Add tests for setting and removing due date
[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_compare_different_tasks(self):
198         # Negative: compare two different tasks
199         t1 = Task(self.tw, description="test task")
200         t2 = Task(self.tw, description="test task")
201
202         t1.save()
203         t2.save()
204
205         self.assertEqual(t1 == t2, False)
206
207     def test_compare_same_task_object(self):
208         # Compare Task object wit itself
209         t = Task(self.tw, description="test task")
210         t.save()
211
212         self.assertEqual(t == t, True)
213
214     def test_compare_same_task(self):
215         # Compare the same task using two different objects
216         t1 = Task(self.tw, description="test task")
217         t1.save()
218
219         t2 = self.tw.tasks.get(uuid=t1['uuid'])
220         self.assertEqual(t1 == t2, True)
221
222     def test_compare_unsaved_tasks(self):
223         # t1 and t2 are unsaved tasks, considered to be unequal
224         # despite the content of data
225         t1 = Task(self.tw, description="test task")
226         t2 = Task(self.tw, description="test task")
227
228         self.assertEqual(t1 == t2, False)
229
230     def test_hash_unsaved_tasks(self):
231         # Considered equal, it's the same object
232         t1 = Task(self.tw, description="test task")
233         t2 = t1
234         self.assertEqual(hash(t1) == hash(t2), True)
235
236     def test_hash_same_task(self):
237         # Compare the hash of the 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.__hash__(), t2.__hash__())
243
244     def test_adding_task_with_priority(self):
245         t = Task(self.tw, description="test task", priority="M")
246         t.save()
247
248     def test_removing_priority_with_none(self):
249         t = Task(self.tw, description="test task", priority="L")
250         t.save()
251
252         # Remove the priority mark
253         t['priority'] = None
254         t.save()
255
256         # Assert that priority is not there after saving
257         self.assertEqual(t['priority'], None)
258
259     def test_adding_task_with_due_time(self):
260         t = Task(self.tw, description="test task", due=datetime.datetime.now())
261         t.save()
262
263     def test_removing_due_time_with_none(self):
264         t = Task(self.tw, description="test task", due=datetime.datetime.now())
265         t.save()
266
267         # Remove the due timestamp
268         t['due'] = None
269         t.save()
270
271         # Assert that due timestamp is no longer there
272         self.assertEqual(t['due'], None)
273
274
275 class AnnotationTest(TasklibTest):
276
277     def setUp(self):
278         super(AnnotationTest, self).setUp()
279         Task(self.tw, description="test task").save()
280
281     def test_adding_annotation(self):
282         task = self.tw.tasks.get()
283         task.add_annotation('test annotation')
284         self.assertEqual(len(task['annotations']), 1)
285         ann = task['annotations'][0]
286         self.assertEqual(ann['description'], 'test annotation')
287
288     def test_removing_annotation(self):
289         task = self.tw.tasks.get()
290         task.add_annotation('test annotation')
291         ann = task['annotations'][0]
292         ann.remove()
293         self.assertEqual(len(task['annotations']), 0)
294
295     def test_removing_annotation_by_description(self):
296         task = self.tw.tasks.get()
297         task.add_annotation('test annotation')
298         task.remove_annotation('test annotation')
299         self.assertEqual(len(task['annotations']), 0)
300
301     def test_removing_annotation_by_obj(self):
302         task = self.tw.tasks.get()
303         task.add_annotation('test annotation')
304         ann = task['annotations'][0]
305         task.remove_annotation(ann)
306         self.assertEqual(len(task['annotations']), 0)
307
308
309 class UnicodeTest(TasklibTest):
310
311     def test_unicode_task(self):
312         Task(self.tw, description="†åßk").save()
313         self.tw.tasks.get()
314
315     def test_non_unicode_task(self):
316         Task(self.tw, description="test task").save()
317         self.tw.tasks.get()