Add files from the old svn, r101.
[matthijs/upstream/mobilegtd.git] / tests / specs / persistence / project_file_spec.py
1 # coding: utf-8
2 from mock import Mock
3 import file_based_spec
4 import unittest
5 from persistence import project_file
6 from persistence.project_file import ProjectFile
7 from model import project
8 from model import action
9 from model import info
10 from model import datetime
11 from persistence.action_file import ActionFile
12 import os
13 from inout import io
14
15
16             
17
18 class ProjectFileBehaviour(file_based_spec.FileBasedBehaviour):
19
20     def setUp(self):
21         super(ProjectFileBehaviour,self).setUp()
22         self.project = self.create_project()
23         self.project_file = ProjectFile(self.project)
24
25     def create_project(self):
26         project = Mock()
27         project.status = self.status()
28         project.name = u'some projectüß'
29         project.actions = self.create_actions()
30         project.observers = []
31         self.info = Mock()
32         self.info.file_string.return_value = 'important info'
33         project.infos = [self.info]
34         return project
35     def create_actions(self):
36         self.action1 = Mock()
37         self.action1.status = action.active
38         self.action1.project_file_string.return_value = 'first action'
39         self.action2 = Mock()
40         self.action2.status = action.inactive
41         self.action2.project_file_string.return_value = 'second action'
42         return [self.action1,self.action2]
43
44     def status(self):
45         return project.active
46
47 #    def test_should_have_registered_itself_as_observer(self):
48 #        self.assertTrue(self.project_file in self.project.observers)
49
50     def test_should_calc_file_name_as_project_name_plus_extension(self):
51         self.assertEqual(self.project_file.file_name(),self.project.name+'.prj')
52
53     def path(self):
54         return self.path_in_subdirectory(self.subdir())
55
56     def path_in_subdirectory(self,subdir):
57         project_file_name = self.project.name+'.prj'
58         if subdir and len(subdir) > 0:
59             return os.path.join('@Projects',subdir,project_file_name)
60         else:
61             return os.path.join('@Projects',project_file_name)
62
63     def test_should_create_an_action_file_if_notified_of_added_action(self):
64         a = Mock()
65         a.observers = []
66         a.status = action.inactive
67         self.project_file.notify(self.project, 'add_action', a, None)
68         self.assertTrue(has_added_action_file_as_observer(a))
69
70
71 class ProjectFileWithNonAsciiCharacterName(ProjectFileBehaviour):
72     def create_project(self):
73         project = super(ProjectFileWithNonAsciiCharacterName,self).create_project()
74         project.name = u'some project with ümläutß'
75         return project
76     
77
78
79 class ExistingProjectFileBehaviour:
80     
81     def setUp(self):
82         super(ExistingProjectFileBehaviour,self).setUp()
83     
84     def assert_moved_file_to_correct_directory_if_status_changes(self,status,subdir):
85         self.create_file()
86         old_status = self.project.status
87         self.project.status = status
88         self.project_file.notify(self.project, 'status', status,old_status)
89         self.assertTrue(os.path.isfile(io.os_encode(self.path_in_subdirectory(subdir))),"Should have moved file to %s"%self.path_in_subdirectory(subdir))
90     
91     def test_should_move_file_correctly_to_review_directory(self):
92         self.assert_moved_file_to_correct_directory_if_status_changes(project.inactive,'@Review')
93
94     def test_should_move_file_correctly_to_active_directory(self):
95         self.assert_moved_file_to_correct_directory_if_status_changes(project.active,'')
96
97     def test_should_move_file_correctly_to_someday_directory(self):
98         self.assert_moved_file_to_correct_directory_if_status_changes(project.someday,'@Someday')
99
100     def test_should_move_file_correctly_to_tickled_with_date_directory(self):
101         self.assert_moved_file_to_correct_directory_if_status_changes(project.Tickled(datetime.date(2009,12,31)), os.path.join('@Tickled','12 December','31 Thursday'))
102     def test_should_move_file_correctly_to_tickled_with_date_in_another_year_directory(self):
103         self.assert_moved_file_to_correct_directory_if_status_changes(project.Tickled(datetime.date(2012,12,31)), os.path.join('@Tickled','2012','12 December','31 Monday'))
104     def test_should_rename_file_if_project_name_changes(self):
105         name = 'new name'
106         self.create_file()
107         self.project_file.notify(self.project, 'name', name)
108         self.project.name = name
109         assert os.path.isfile(self.path())
110         
111     def test_should_calc_path_correctly(self):
112         self.assertEqual(self.project_file.path(),self.path())
113
114     def test_should_write_if_notified_of_changes(self):
115         self.project_file.notify(self.project, 'add_action', Mock(),None)        
116         self.assertCreatedFile(self.path())
117
118
119
120
121 class WritingProjectFileBehaviour(ExistingProjectFileBehaviour):
122     def test_should_write_the_project_description_in_file(self):
123 #        pass
124         self.project_file.write()
125         content = self.file_content()
126         assert len(content) > 0
127         assert self.info.file_string() in content
128         assert self.action1.project_file_string() in content
129         assert self.action2.project_file_string() in content
130
131
132
133 class ActiveProjectFileBehaviour(ProjectFileBehaviour,ExistingProjectFileBehaviour):
134
135     def status(self):
136         return project.active
137
138     def subdir(self):
139         return ''
140
141         
142
143
144 class SomedayProjectFileBehaviour(ProjectFileBehaviour,ExistingProjectFileBehaviour):
145
146     def status(self):
147         return project.someday
148
149     def subdir(self):
150         return '@Someday'        
151
152
153 class InactiveProjectFileBehaviour(ProjectFileBehaviour,ExistingProjectFileBehaviour):
154     def status(self):
155         return project.inactive
156         
157     def subdir(self):
158         return '@Review'
159
160
161
162 class ProjectFileReaderBehaviour(ProjectFileBehaviour,ExistingProjectFileBehaviour):
163
164 #    def setUp(self):
165 #        super(ProjectFileReaderBehaviour,self).setUp()
166 #        self.project.add_action.side_effect = lambda a:self.project_file.notify(self.project, 'add_action', a, None)
167         
168     def create_project(self):
169         self.original_project = self.create_original_project()
170         self.original_project.add_info(info.Info('some info'))
171         active_action = action.Action('active action','Online/Google',status=action.inactive)
172         self.original_project.add_action(active_action)
173         p_file = ProjectFile(self.original_project)
174         self.write(p_file.file_string(),p_file.path())
175 #        self.original_project.observers.remove(p_file)
176         p,self.actions,self.infos = project_file.read(p_file.path())
177         for a in self.actions:
178             p.add_action(a)
179         for i in self.infos:    
180             p.add_info(i)
181         return p
182
183     def create_original_project(self):
184         self.project_name = u'Exämple Project'
185         return project.Project(self.project_name)
186
187     def create_actions(self):
188         return self.actions
189
190     def path(self):
191         return self.project_file.path()
192     
193     def test_should_read_the_project_name_correctly(self):
194         self.assertEqual(self.project.name,self.project_name)
195
196     def test_should_infer_the_status_from_the_path(self):
197         self.assertEqual(self.project.status,self.original_project.status)
198
199     def test_should_read_the_infos_correctly(self):
200         self.assertEqual(self.project.infos,[info.Info('some info')])
201
202     def test_should_read_the_actions_correctly(self):
203         a = action.Action('active action','Online/Google',status=action.inactive)
204         a.project = self.project
205         self.assertEqual(self.project.actions,[a])
206         
207 #    def test_should_create_action_files_for_all_actions(self):
208 #        for a in self.project.actions:
209 #            self.assertTrue(has_added_action_file_as_observer(a))
210
211 class DoneProjectFileReaderBehaviour(ProjectFileReaderBehaviour):
212     def create_original_project(self):
213         p = ProjectFileReaderBehaviour.create_original_project(self)
214         p.status = project.done
215         return p
216
217
218 def has_added_action_file_as_observer(a):
219     has_action_file=False
220     for o in a.observers:
221         if type(o) == ActionFile and o.action == a:
222             has_action_file=True
223     return has_action_file