Merge lp:~nataliabidart/magicicada-gui/expand-status into lp:magicicada-gui
- expand-status
- Merge into trunk
Proposed by
Natalia Bidart
Status: | Merged | ||||
---|---|---|---|---|---|
Approved by: | Facundo Batista | ||||
Approved revision: | 27 | ||||
Merged at revision: | 24 | ||||
Proposed branch: | lp:~nataliabidart/magicicada-gui/expand-status | ||||
Merge into: | lp:magicicada-gui | ||||
Prerequisite: | lp:~nataliabidart/magicicada-gui/set-initial-state | ||||
Diff against target: |
383 lines (+132/-63) 3 files modified
data/ui/gui.glade (+2/-1) magicicada/__init__.py (+18/-10) magicicada/tests/test_magicicada.py (+112/-52) |
||||
To merge this branch: | bzr merge lp:~nataliabidart/magicicada-gui/expand-status | ||||
Related bugs: |
|
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
chicharreros | Pending | ||
Review via email: mp+25899@code.launchpad.net |
Commit message
Description of the change
Status label tweaks: added connection status, added ellipsize, added initial status.
To post a comment you must log in.
- 28. By Natalia Bidart
-
Merged trunk in.
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | === modified file 'data/ui/gui.glade' |
2 | --- data/ui/gui.glade 2010-05-16 21:43:51 +0000 |
3 | +++ data/ui/gui.glade 2010-05-24 16:14:33 +0000 |
4 | @@ -199,13 +199,14 @@ |
5 | </object> |
6 | <packing> |
7 | <property name="expand">False</property> |
8 | + <property name="padding">3</property> |
9 | <property name="position">0</property> |
10 | </packing> |
11 | </child> |
12 | <child> |
13 | <object class="GtkLabel" id="status_label"> |
14 | <property name="visible">True</property> |
15 | - <property name="label" translatable="yes">Service not started, click Start to continue.</property> |
16 | + <property name="ellipsize">end</property> |
17 | </object> |
18 | <packing> |
19 | <property name="position">1</property> |
20 | |
21 | === modified file 'magicicada/__init__.py' |
22 | --- magicicada/__init__.py 2010-05-23 10:23:35 +0000 |
23 | +++ magicicada/__init__.py 2010-05-24 16:14:33 +0000 |
24 | @@ -29,16 +29,16 @@ |
25 | gtk2reactor.install() |
26 | |
27 | from magicicada import syncdaemon |
28 | -from magicicada.helpers import get_data_file, get_builder, NO_OP, print_debug |
29 | +from magicicada.helpers import get_data_file, get_builder, NO_OP |
30 | |
31 | CONTENT_QUEUE = 'content' |
32 | META_QUEUE = 'meta' |
33 | |
34 | class MagicicadaUI(object): |
35 | |
36 | + STATUS_JOINER = " - " |
37 | STATUS = { |
38 | - 'started': _('Service started, click Connect to continue.'), |
39 | - 'connected': _('Service connected. Doing internal synchronization...'), |
40 | + 'initial': _('Service is not started, click Start to continue.'), |
41 | } |
42 | |
43 | def __init__(self, launchpad_available=False, on_destroy=NO_OP, |
44 | @@ -142,7 +142,6 @@ |
45 | self.disconnect.set_sensitive(False) |
46 | self.sd.disconnect() |
47 | |
48 | - @print_debug |
49 | def on_status_icon_activate(self, widget, data=None): |
50 | """Systray icon was clicked.""" |
51 | if self.main_window.get_property('visible'): |
52 | @@ -171,6 +170,11 @@ |
53 | self._activate_indicator(self.is_connected, sensitive=False) |
54 | self._activate_indicator(self.is_online, sensitive=False) |
55 | |
56 | + cs = self.sd.current_state |
57 | + self.on_status_changed(cs.name, cs.description) |
58 | + self.on_meta_queue_changed(self.sd.meta_queue) |
59 | + self.on_content_queue_changed(self.sd.content_queue) |
60 | + |
61 | def on_connected(self, *args, **kwargs): |
62 | """Callback'ed when syncadaemon is connected.""" |
63 | self.connect.hide() |
64 | @@ -199,12 +203,14 @@ |
65 | self._activate_indicator(self.is_online, sensitive=False) |
66 | |
67 | def on_status_changed(self, name=None, description=None, |
68 | - is_error=False, is_connected=True, |
69 | - is_online=True, queues=None, connection=None): |
70 | + is_error=False, is_connected=True, is_online=True, |
71 | + queues=None, connection=None): |
72 | """Callback'ed when the SD status changed.""" |
73 | - if description is None: |
74 | - description = '' |
75 | - self.status_label.set_text(description) |
76 | + values = (v for v in (name, description, connection) if v) |
77 | + text = self.STATUS_JOINER.join(values) |
78 | + if not (text or self.sd.current_state.is_started): |
79 | + text = self.STATUS['initial'] |
80 | + self.status_label.set_text(text) |
81 | |
82 | def _on_queue_changed(self, queue_name, items, *args, **kwargs): |
83 | """Callback'ed when a queue changed.""" |
84 | @@ -257,4 +263,6 @@ |
85 | |
86 | self.on_meta_queue_changed(self.sd.meta_queue) |
87 | self.on_content_queue_changed(self.sd.content_queue) |
88 | - self.on_status_changed(description=current_state.description) |
89 | + self.on_status_changed(name=current_state.name, |
90 | + description=current_state.description, |
91 | + connection=current_state.connection) |
92 | |
93 | === modified file 'magicicada/tests/test_magicicada.py' |
94 | --- magicicada/tests/test_magicicada.py 2010-05-23 10:23:35 +0000 |
95 | +++ magicicada/tests/test_magicicada.py 2010-05-24 16:14:33 +0000 |
96 | @@ -18,6 +18,8 @@ |
97 | |
98 | """Tests for magicicada.""" |
99 | |
100 | +import pango |
101 | + |
102 | from twisted.trial.unittest import TestCase |
103 | |
104 | from magicicada import MagicicadaUI, CONTENT_QUEUE, META_QUEUE, syncdaemon |
105 | @@ -28,6 +30,10 @@ |
106 | """A faked syncdaemon.""" |
107 | |
108 | def __init__(self): |
109 | + self.current_state = syncdaemon.State() |
110 | + self.meta_queue = [] |
111 | + self.content_queue = [] |
112 | + |
113 | self.on_started_callback = NO_OP |
114 | self.on_stopped_callback = NO_OP |
115 | self.on_connected_callback = NO_OP |
116 | @@ -38,14 +44,11 @@ |
117 | self.content_queue_changed_callback = NO_OP |
118 | self.meta_queue_changed_callback = NO_OP |
119 | self.shutdown = NO_OP |
120 | - self.start = NO_OP |
121 | - self.quit = NO_OP |
122 | - self.connect = NO_OP |
123 | - self.disconnect = NO_OP |
124 | - |
125 | - self.current_state = syncdaemon.State() |
126 | - self.meta_queue = [] |
127 | - self.content_queue = [] |
128 | + self.start = lambda: setattr(self.current_state, 'is_started', True) |
129 | + self.quit = lambda: setattr(self.current_state, 'is_started', False) |
130 | + self.connect = lambda: setattr(self.current_state, 'is_connected', True) |
131 | + self.disconnect = \ |
132 | + lambda: setattr(self.current_state, 'is_connected', False) |
133 | |
134 | |
135 | class MagicicadaUITestCase(TestCase): |
136 | @@ -62,6 +65,17 @@ |
137 | self.ui.on_main_window_destroy(self.ui.main_window) |
138 | self._called = False |
139 | |
140 | + def do_start(self): |
141 | + """Simulate that start fully happened.""" |
142 | + self.ui.on_start_clicked(self.ui.start) |
143 | + self.ui.on_started() |
144 | + |
145 | + def do_connect(self): |
146 | + """Simulate that connect fully happened.""" |
147 | + self.do_start() |
148 | + self.ui.on_connect_clicked(self.ui.connect) |
149 | + self.ui.on_connected() |
150 | + |
151 | def assert_indicator_disabled(self, indicator): |
152 | """Test that 'indicator' is not sensitive.""" |
153 | self.assertFalse(indicator.is_sensitive(), 'indicator is not sensitive') |
154 | @@ -150,8 +164,7 @@ |
155 | |
156 | def test_on_connect_clicked(self): |
157 | """Test on_connect_clicked.""" |
158 | - self.ui.on_start_clicked(self.ui.start) # need to be started |
159 | - self.ui.on_started() |
160 | + self.do_start() # need to be started |
161 | self.ui.on_connect_clicked(self.ui.connect) |
162 | |
163 | self.assertTrue(self.ui.connect.get_property('visible')) |
164 | @@ -170,8 +183,7 @@ |
165 | |
166 | def test_on_stop_clicked(self): |
167 | """Test on_stop_clicked.""" |
168 | - self.ui.on_start_clicked(self.ui.start) |
169 | - self.ui.on_started() |
170 | + self.do_start() |
171 | assert not self.ui.widget_enabled(self.ui.disconnect) |
172 | self.patch(self.ui, 'on_disconnect_clicked', self.set_called) |
173 | self.ui.on_stop_clicked(self.ui.stop) |
174 | @@ -188,10 +200,7 @@ |
175 | |
176 | def test_on_stop_clicked_if_connected(self): |
177 | """Test on_stop_clicked.""" |
178 | - self.ui.on_start_clicked(self.ui.start) |
179 | - self.ui.on_started() |
180 | - self.ui.on_connect_clicked(self.ui.connect) |
181 | - self.ui.on_connected() |
182 | + self.do_connect() |
183 | self.patch(self.ui, 'on_disconnect_clicked', self.set_called) |
184 | self.ui.on_stop_clicked(self.ui.stop) |
185 | |
186 | @@ -205,10 +214,7 @@ |
187 | |
188 | def test_on_disconnect_clicked(self): |
189 | """Test on_disconnect_clicked.""" |
190 | - self.ui.on_start_clicked(self.ui.start) |
191 | - self.ui.on_started() |
192 | - self.ui.on_connect_clicked(self.ui.connect) |
193 | - self.ui.on_connected() |
194 | + self.do_connect() |
195 | self.ui.on_disconnect_clicked(self.ui.disconnect) |
196 | |
197 | self.assertFalse(self.ui.connect.get_property('visible')) |
198 | @@ -329,6 +335,14 @@ |
199 | |
200 | self.assert_queue_store_correct(self.queue_store, data) |
201 | |
202 | + def test_on_stopped_updates_queue(self): |
203 | + """On SD stoppped, the UI updates the queue state.""" |
204 | + cb = 'on_%s_queue_changed' % self.queue |
205 | + self.patch(self.ui, cb, self.set_called) |
206 | + self.ui.on_stopped() |
207 | + self.assertTrue(self._called, |
208 | + '%s was called on_stopped.' % cb) |
209 | + |
210 | |
211 | class MagicicadaUIContentQueueTestCase(_MagicicadaUIQueueTestCase): |
212 | """UI test cases for content queue view.""" |
213 | @@ -345,28 +359,91 @@ |
214 | class MagicicadaUIStatusTestCase(MagicicadaUITestCase): |
215 | """UI test cases for the status label.""" |
216 | |
217 | + def assert_status_label_correct(self, name=None, description=None, |
218 | + connection=None, expected=None): |
219 | + """Test that the status label is of the form name: description.""" |
220 | + if expected is None: |
221 | + assert name is not None |
222 | + assert description is not None |
223 | + assert connection is not None |
224 | + values = (name, description, connection) |
225 | + expected = self.ui.STATUS_JOINER.join(values) |
226 | + |
227 | + actual = self.ui.status_label.get_text() |
228 | + msg = 'status label test must be "%s" (got "%s" instead).' |
229 | + self.assertEqual(expected, actual, msg % (expected, actual)) |
230 | + |
231 | def test_callback_is_connected(self): |
232 | """Status callback is connected.""" |
233 | self.assertEqual(self.ui.sd.status_changed_callback, |
234 | self.ui.on_status_changed, |
235 | 'status_changed callback must be set') |
236 | |
237 | + def test_status_label_ellipsizes(self): |
238 | + """The status label ellipsizes.""" |
239 | + expected = pango.ELLIPSIZE_END |
240 | + actual = self.ui.status_label.get_ellipsize() |
241 | + self.assertEqual(expected, actual, 'label ellipsizes is ELLIPSIZE_END.') |
242 | + |
243 | def test_on_status_changed_updates_status_label(self): |
244 | - """On status changed the status label is updated.""" |
245 | - kwargs = dict(name='test', description='the status for testing', |
246 | - is_error=False, is_connected=True, is_online=False, |
247 | - queues=None, connection=None) |
248 | + """On status changed, the status label is updated.""" |
249 | + name = 'TEST' |
250 | + description = 'the status for testing' |
251 | + connection = 'funny funny connection' |
252 | + kwargs = dict(name=name, description=description, connection=connection) |
253 | + |
254 | + # usual case, all values are defined |
255 | self.ui.on_status_changed(**kwargs) |
256 | - self.assertEqual(self.ui.status_label.get_text(), kwargs['description']) |
257 | + self.assert_status_label_correct(**kwargs) |
258 | + |
259 | + def test_on_status_changed_updates_status_label_even_on_weird_cases(self): |
260 | + """On status changed, the status label is updated.""" |
261 | + name = 'TEST' |
262 | + description = 'the status for testing' |
263 | + connection = 'funny funny connection' |
264 | + kwargs = dict(name=name, description=description, connection=connection) |
265 | + |
266 | + keywords = ('name', 'description', 'connection') # need ordering |
267 | + for attr in keywords: |
268 | + old_value = kwargs[attr] |
269 | + |
270 | + # some weird cases: attr is '' or None |
271 | + for value in ('', None): |
272 | + kwargs[attr] = value |
273 | + self.ui.on_status_changed(**kwargs) |
274 | + others = (kwargs[k] for k in keywords if k != attr) |
275 | + expected = self.ui.STATUS_JOINER.join(others) |
276 | + self.assert_status_label_correct(expected=expected) |
277 | + |
278 | + kwargs[attr] = old_value |
279 | |
280 | def test_update_is_correct_for_status_label(self): |
281 | """Correctly updates the status label.""" |
282 | - expected = 'dummy test' |
283 | - self.ui.sd.current_state._set(description=expected) |
284 | + name = 'TEST' |
285 | + description = 'the status for testing' |
286 | + connection = 'funny funny connection' |
287 | + kwargs = dict(name=name, description=description, connection=connection) |
288 | + self.ui.sd.current_state._set(**kwargs) |
289 | |
290 | self.ui.update() |
291 | - |
292 | - self.assertEqual(expected, self.ui.status_label.get_text()) |
293 | + self.assert_status_label_correct(**kwargs) |
294 | + |
295 | + def test_on_stopped_updates_status_label(self): |
296 | + """On SD stoppped, the UI updates the status label.""" |
297 | + self.patch(self.ui, 'on_status_changed', self.set_called) |
298 | + self.ui.on_stopped() |
299 | + self.assertTrue(self._called, |
300 | + 'on_status_changed was called on_stopped.') |
301 | + |
302 | + def test_status_label_default_if_not_started(self): |
303 | + """Status label is the default if not started.""" |
304 | + self.assert_status_label_correct(expected=self.ui.STATUS['initial']) |
305 | + |
306 | + def test_status_label_empty_if_started_and_no_name_nor_desc(self): |
307 | + """Status label is empty if started but no name and no description.""" |
308 | + self.do_start() |
309 | + self.ui.on_status_changed(name=None, description=None) |
310 | + self.assert_status_label_correct(expected='') |
311 | |
312 | |
313 | class MagicicadaUIConnectionTestCase(MagicicadaUITestCase): |
314 | @@ -425,10 +502,7 @@ |
315 | |
316 | def test_on_started_is_correct(self): |
317 | """On SD started, the UI enables connect and indicator.""" |
318 | - # must have click start first |
319 | - self.ui.on_start_clicked(self.ui.start) |
320 | - |
321 | - self.ui.on_started() |
322 | + self.do_start() |
323 | |
324 | self.assertTrue(self.ui.widget_enabled(self.ui.stop)) |
325 | self.assertTrue(self.ui.widget_enabled(self.ui.connect)) |
326 | @@ -438,11 +512,7 @@ |
327 | |
328 | def test_on_connected_is_correct(self): |
329 | """On SD connected, the UI enables indicator.""" |
330 | - self.ui.on_start_clicked(self.ui.start) |
331 | - self.ui.on_started() |
332 | - self.ui.on_connect_clicked(self.ui.start) |
333 | - |
334 | - self.ui.on_connected() |
335 | + self.do_connect() |
336 | |
337 | self.assertTrue(self.ui.widget_enabled(self.ui.disconnect)) |
338 | self.assert_indicator_ready(self.ui.is_started) |
339 | @@ -451,10 +521,7 @@ |
340 | |
341 | def test_on_online_is_correct(self): |
342 | """On SD online, the UI enables indicator.""" |
343 | - self.ui.on_start_clicked(self.ui.start) |
344 | - self.ui.on_started() |
345 | - self.ui.on_connect_clicked(self.ui.connect) |
346 | - self.ui.on_connected() |
347 | + self.do_connect() |
348 | |
349 | self.ui.on_online() |
350 | |
351 | @@ -464,8 +531,7 @@ |
352 | |
353 | def test_on_stopped_is_correct(self): |
354 | """On SD stopped, the UI disables stop and indicator.""" |
355 | - self.ui.on_start_clicked(self.ui.start) |
356 | - self.ui.on_started() |
357 | + self.do_start() |
358 | self.ui.on_stop_clicked(self.ui.stop) |
359 | |
360 | self.ui.on_stopped() |
361 | @@ -478,10 +544,7 @@ |
362 | |
363 | def test_on_disconnected_is_correct(self): |
364 | """On SD disconnected, the UI disables connect and indicator.""" |
365 | - self.ui.on_start_clicked(self.ui.start) |
366 | - self.ui.on_started() |
367 | - self.ui.on_connect_clicked(self.ui.connect) |
368 | - self.ui.on_connected() |
369 | + self.do_connect() |
370 | self.ui.on_disconnect_clicked(self.ui.disconnect) |
371 | |
372 | self.ui.on_disconnected() |
373 | @@ -493,10 +556,7 @@ |
374 | |
375 | def test_on_offline_is_correct(self): |
376 | """On SD offline, the UI disables indicator.""" |
377 | - self.ui.on_start_clicked(self.ui.start) |
378 | - self.ui.on_started() |
379 | - self.ui.on_connect_clicked(self.ui.connect) |
380 | - self.ui.on_connected() |
381 | + self.do_connect() |
382 | |
383 | self.ui.on_offline() |
384 |