Merge lp:~nataliabidart/magicicada-gui/multiple-metadata-for-real into lp:magicicada-gui

Proposed by Natalia Bidart
Status: Merged
Approved by: Natalia Bidart
Approved revision: 69
Merged at revision: 66
Proposed branch: lp:~nataliabidart/magicicada-gui/multiple-metadata-for-real
Merge into: lp:magicicada-gui
Diff against target: 588 lines (+183/-114)
4 files modified
data/ui/gui.glade (+3/-2)
magicicada/__init__.py (+46/-37)
magicicada/tests/test_magicicada.py (+132/-74)
pylintrc (+2/-1)
To merge this branch: bzr merge lp:~nataliabidart/magicicada-gui/multiple-metadata-for-real
Reviewer Review Type Date Requested Status
Facundo Batista Approve
Review via email: mp+30853@code.launchpad.net

Description of the change

Multiple metadata windows are now supported. Yeyyyy!

To post a comment you must log in.
Revision history for this message
Facundo Batista (facundo) wrote :

===============================================================================
[FAIL]: magicicada.tests.test_magicicada.MagicicadaUIMetadataTestCase.test_metadata_dialog_properties

Traceback (most recent call last):
  File "/home/facundo/devel/reps/magicicada/review_multiple-metadata-for-real/magicicada/tests/test_magicicada.py", line 1268, in test_metadata_dialog_properties
    self.assert_dialog_properties(dialog=dialog, title=title, modal=False)
  File "/home/facundo/devel/reps/magicicada/review_multiple-metadata-for-real/magicicada/tests/test_magicicada.py", line 221, in assert_dialog_properties
    '%s must be centered.' % dialog_name)
twisted.trial.unittest.FailTest: None must be centered.
not equal:
a = <enum GTK_WIN_POS_CENTER of type GtkWindowPosition>
b = <enum GTK_WIN_POS_MOUSE of type GtkWindowPosition>

-------------------------------------------------------------------------------
Ran 336 tests in 11.971s

FAILED (failures=1, successes=335)

review: Needs Fixing
68. By Natalia Bidart

Fixing failing test.

Revision history for this message
Natalia Bidart (nataliabidart) wrote :

> ==============================================================================
> =
> [FAIL]: magicicada.tests.test_magicicada.MagicicadaUIMetadataTestCase.test_met
> adata_dialog_properties

Fixed!

69. By Natalia Bidart

Merged trunk in.

Revision history for this message
Facundo Batista (facundo) wrote :

Looks ok now!

review: Approve

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-07-18 20:58:35 +0000
3+++ data/ui/gui.glade 2010-08-01 14:53:41 +0000
4@@ -256,13 +256,13 @@
5 </packing>
6 </child>
7 <child>
8- <object class="GtkToolButton" id="raw_metadata">
9+ <object class="GtkToolButton" id="metadata">
10 <property name="visible">True</property>
11 <property name="sensitive">False</property>
12 <property name="label" translatable="yes">Metadata</property>
13 <property name="use_underline">True</property>
14 <property name="stock_id">gtk-find</property>
15- <signal name="clicked" handler="on_raw_metadata_clicked"/>
16+ <signal name="clicked" handler="on_metadata_clicked"/>
17 </object>
18 <packing>
19 <property name="expand">False</property>
20@@ -980,6 +980,7 @@
21 </object>
22 <object class="GtkFileChooserDialog" id="file_chooser">
23 <property name="border_width">5</property>
24+ <property name="window_position">center</property>
25 <property name="type_hint">normal</property>
26 <property name="has_separator">False</property>
27 <property name="create_folders">False</property>
28
29=== modified file 'magicicada/__init__.py'
30--- magicicada/__init__.py 2010-07-18 20:58:35 +0000
31+++ magicicada/__init__.py 2010-08-01 14:53:41 +0000
32@@ -57,6 +57,13 @@
33 logger.addHandler(console)
34
35
36+# Instance of 'A' has no 'y' member
37+# pylint: disable-msg=E1101
38+
39+# Unused argument, we need them for GTK callbacks
40+# pylint: disable-msg=W0613
41+
42+
43 class MagicicadaUI(object):
44 """Magicicada GUI main class."""
45
46@@ -97,8 +104,7 @@
47 'shares_to_me_view', 'shares_to_me_store', 'shares_to_me_close',
48 'shares_to_others', 'shares_to_others_dialog', # shares_to_others
49 'shares_to_others_view', 'shares_to_others_store',
50- 'shares_to_others_close',
51- 'raw_metadata', # raw metadata
52+ 'shares_to_others_close', 'metadata', # metadata
53 'is_started', 'is_connected', 'is_online', # status bar images
54 'status_label', 'status_icon', # status label and systray icon
55 'metaq_view', 'contentq_view', # queues tree views
56@@ -117,7 +123,7 @@
57 self._make_view_sortable('shares_to_me')
58 self._make_view_sortable('shares_to_others')
59
60- self.raw_metadata_dialog = self._new_metadata_dialog()
61+ self.metadata_dialogs = {}
62 self.volumes = (self.folders, self.shares_to_me, self.shares_to_others)
63 self.windows = (self.main_window, self.about_dialog,
64 self.folders_dialog)
65@@ -146,7 +152,6 @@
66 self.widget_is_visible = lambda w: w.get_property('visible')
67 self.widget_enabled = lambda w: self.widget_is_visible(w) and \
68 w.is_sensitive()
69- self.last_metadata_path = None
70 self.update()
71
72 def _make_view_sortable(self, view_name):
73@@ -159,23 +164,24 @@
74 col.connect('clicked', self.on_store_sort_column_changed, i, store)
75 self._sorting_order[store][i] = gtk.SORT_ASCENDING
76
77- def _new_metadata_dialog(self):
78+ def _new_metadata_dialog(self, path):
79 """Return a new metadata dialog."""
80- dialog = gtk.Dialog(title='Raw metadata', parent=self.main_window,
81+ dialog = gtk.Dialog(title='Metadata for %s' % path,
82+ parent=self.main_window,
83 flags=gtk.DIALOG_NO_SEPARATOR,
84 buttons=(gtk.STOCK_CLOSE, gtk.RESPONSE_CLOSE))
85 dialog.set_size_request(600, 300)
86- dialog.set_position(gtk.WIN_POS_CENTER)
87- setattr(self, 'raw_metadata_dialog', dialog)
88+ # gtk.WIN_POS_CENTER makes dialog overlap
89+ dialog.set_position(gtk.WIN_POS_MOUSE)
90
91 close_button = dialog.action_area.get_children()[-1]
92- close_button.connect('clicked', self.on_raw_metadata_close_clicked)
93- close_button.connect('activate', self.on_raw_metadata_close_clicked)
94- setattr(self, 'raw_metadata_close', close_button)
95+ close_button.connect('clicked', self.on_metadata_close_clicked, path)
96+ close_button.connect('activate', self.on_metadata_close_clicked, path)
97+ dialog.close = close_button
98
99 image = gtk.Image()
100 image.set_from_animation(self.loading_animation)
101- setattr(self, 'raw_metadata_image', image)
102+ dialog.image = image
103
104 dialog.get_child().add(image)
105
106@@ -183,9 +189,9 @@
107 text_view.set_editable(False)
108 text_view.set_wrap_mode(gtk.WRAP_WORD)
109 dialog.get_child().add(text_view)
110- setattr(self, 'raw_metadata_view', text_view)
111+ dialog.view = text_view
112
113- dialog.hide() # XXX to be fixed later
114+ self.metadata_dialogs[path] = dialog
115 return dialog
116
117 # GTK callbacks
118@@ -215,7 +221,7 @@
119 """Stop syncdaemon."""
120 for v in self.volumes:
121 v.set_sensitive(False)
122- self.raw_metadata.set_sensitive(False)
123+ self.metadata.set_sensitive(False)
124
125 if self.widget_enabled(self.disconnect):
126 self.on_disconnect_clicked(self.disconnect)
127@@ -301,26 +307,28 @@
128
129 def on_file_chooser_show(self, widget, data=None):
130 """Close the file_chooser dialog."""
131- if self.last_metadata_path is None:
132- self.file_chooser.set_current_folder(self._u1_root)
133-
134- def on_raw_metadata_close_clicked(self, widget, data=None):
135- """Close the raw_metadata dialog."""
136- self.raw_metadata_dialog.hide()
137-
138- def on_raw_metadata_clicked(self, widget, data=None):
139- """Show raw metadata for a path choosen by the user."""
140+ #if self.last_metadata_path is None:
141+ self.file_chooser.set_current_folder(self._u1_root)
142+
143+ def on_metadata_close_clicked(self, widget, path):
144+ """Close the metadata dialog."""
145+ self.metadata_dialogs[path].destroy()
146+
147+ def on_metadata_clicked(self, widget, data=None):
148+ """Show metadata for a path choosen by the user."""
149 res = self.file_chooser.run()
150 self.file_chooser.hide()
151 if res != gtk.FILE_CHOOSER_ACTION_OPEN:
152 return
153
154- self.last_metadata_path = self.file_chooser.get_filename()
155- self.sd.get_metadata(path=self.last_metadata_path)
156- self.raw_metadata_view.hide()
157- self.raw_metadata_image.show()
158- self._start_loading(self.raw_metadata_image)
159- self.raw_metadata_dialog.show()
160+ path = self.file_chooser.get_filename()
161+ assert path is not None
162+ dialog = self._new_metadata_dialog(path)
163+ self.sd.get_metadata(path)
164+ dialog.view.hide()
165+ dialog.image.show()
166+ self._start_loading(dialog.image)
167+ dialog.show()
168
169 def on_status_icon_activate(self, widget, data=None):
170 """Systray icon was clicked."""
171@@ -362,7 +370,7 @@
172
173 for v in self.volumes:
174 v.set_sensitive(True)
175- self.raw_metadata.set_sensitive(True)
176+ self.metadata.set_sensitive(True)
177
178 self._update_queues_and_status(self.sd.current_state)
179
180@@ -457,14 +465,15 @@
181 @log(logger)
182 def on_metadata_ready(self, path, metadata):
183 """Lower layer has the requested metadata for 'path'."""
184- logger.debug('on_metadata_ready: path: %r, last_metadata_path: %r',
185- path, self.last_metadata_path)
186- if path != self.last_metadata_path:
187+ logger.debug('on_metadata_ready: path: %r', path)
188+ if path not in self.metadata_dialogs:
189 return
190- self.raw_metadata_image.hide()
191- self.raw_metadata_view.show()
192+
193+ dialog = self.metadata_dialogs[path]
194+ dialog.image.hide()
195+ dialog.view.show()
196 text = '\n'.join('%s: %s' % i for i in metadata.iteritems())
197- self.raw_metadata_view.get_buffer().set_text(text)
198+ dialog.view.get_buffer().set_text(text)
199
200 # custom
201
202
203=== modified file 'magicicada/tests/test_magicicada.py'
204--- magicicada/tests/test_magicicada.py 2010-07-28 21:48:34 +0000
205+++ magicicada/tests/test_magicicada.py 2010-08-01 14:53:41 +0000
206@@ -39,9 +39,16 @@
207
208 # It's ok to access private data in the test suite
209 # pylint: disable-msg=W0212
210+
211 # Arguments number differs from overridden method
212 # pylint: disable-msg=W0221
213
214+# Instance of 'A' has no 'y' member
215+# pylint: disable-msg=E1101
216+
217+# Instance of 'A' has no 'y' member (but some types could not be inferred)
218+# pylint: disable-msg=E1103
219+
220
221 def process_gtk_pendings():
222 """Process all gtk pending events."""
223@@ -74,7 +81,7 @@
224 """A faked syncdaemon."""
225
226 def __init__(self):
227- self._meta_path = None
228+ self._meta_paths = []
229
230 self.current_state = syncdaemon.State()
231 self.meta_queue = []
232@@ -100,7 +107,7 @@
233 'is_connected', True)
234 self.disconnect = lambda: \
235 setattr(self.current_state, 'is_connected', False)
236- self.get_metadata = lambda path: setattr(self, '_meta_path', path)
237+ self.get_metadata = lambda path: self._meta_paths.append(path)
238
239
240 class MagicicadaUITestCase(TestCase):
241@@ -220,10 +227,12 @@
242 self.assertTrue(sensitive if enabled else not sensitive,
243 msg % (widget_name, '' if enabled else 'not '))
244
245- def assert_dialog_properties(self, dialog_name, title, size=(600, 300),
246- modal=True):
247+ def assert_dialog_properties(self, dialog_name=None, title=None,
248+ size=(600, 300), modal=True, dialog=None):
249 """The dialog 'dialog_name' has correct properties."""
250- dialog = getattr(self.ui, dialog_name)
251+ assert (dialog_name is None) ^ (dialog is None)
252+ if dialog is None:
253+ dialog = getattr(self.ui, dialog_name)
254 actual = dialog.size_request()
255 msg = 'size must be %s (got %s instead).'
256 self.assertEquals(size, actual, msg % (size, actual))
257@@ -233,8 +242,10 @@
258 msg % (dialog_name, '' if modal else 'not '))
259
260 position = dialog.get_property('window-position')
261- self.assertEqual(gtk.WIN_POS_CENTER, position,
262- '%s must be centered.' % dialog_name)
263+ expected = gtk.WIN_POS_CENTER if dialog_name is not None else \
264+ gtk.WIN_POS_MOUSE
265+ msg = 'dialog must have %s position (got %s instead).'
266+ self.assertEqual(expected, position, msg % (expected, position))
267
268 actual = dialog.get_title()
269 msg = '%s title must be %s (got %s instead)'
270@@ -1046,14 +1057,14 @@
271 def test_volume_sorting(self):
272 """Test volume panel can be re-sorted."""
273 for i, col in enumerate(self.volume_view.get_columns()):
274- col.clicked() # click on the column
275+ col.clicked() # click on the column
276 self.assert_sort_order_correct(col, i, gtk.SORT_ASCENDING)
277 self.assert_sort_indicator_correct(col)
278
279- col.clicked() # click on the column, sort order must change
280+ col.clicked() # click on the column, sort order must change
281 self.assert_sort_order_correct(col, i, gtk.SORT_DESCENDING)
282
283- col.clicked() # click again, sort order must be the first one
284+ col.clicked() # click again, sort order must be the first one
285 self.assert_sort_order_correct(col, i, gtk.SORT_ASCENDING)
286
287
288@@ -1125,7 +1136,7 @@
289 class MagicicadaUIMetadataTestCase(MagicicadaUITestCase):
290 """UI test cases for metadata display."""
291
292- name = 'raw_metadata'
293+ name = 'metadata'
294
295 def setUp(self):
296 """Init."""
297@@ -1138,23 +1149,38 @@
298 s = super(MagicicadaUIMetadataTestCase, self)
299 s.assert_widget_availability(self.name, enabled)
300
301- def assert_dialog_visibility(self, dialog, text_view, image):
302+ def assert_dialog_visibility(self, dialog, text_view, image, path=None):
303 """Check the visibility for dialog, text_view and image."""
304+ if path is None:
305+ path = self.path
306+
307 msg = '%s visibility should be %s (got %s instead).'
308- visible = self.ui.widget_is_visible(self.ui.raw_metadata_dialog)
309+ metadata_dialog = self.ui.metadata_dialogs[path]
310+ visible = self.ui.widget_is_visible(metadata_dialog)
311 self.assertEqual(dialog, visible,
312- msg % ('raw_metadata_dialog', dialog, visible))
313+ msg % ('metadata_dialog', dialog, visible))
314
315- visible = self.ui.widget_is_visible(self.ui.raw_metadata_view)
316+ visible = self.ui.widget_is_visible(metadata_dialog.view)
317 self.assertEqual(text_view, visible,
318- msg % ('raw_metadata_view', text_view, visible))
319+ msg % ('metadata_view', text_view, visible))
320
321- visible = self.ui.widget_is_visible(self.ui.raw_metadata_image)
322+ visible = self.ui.widget_is_visible(metadata_dialog.image)
323 self.assertEqual(image, visible,
324- msg % ('raw_metadata_image', image, visible))
325-
326- def test_raw_metadata_are_disabled_until_started(self):
327- """Raw metadata button is disabled until online."""
328+ msg % ('metadata_image', image, visible))
329+
330+ def assert_buffer_content(self, path, expected):
331+ """Check that the buffer content is correct for 'path'."""
332+ buff = self.ui.metadata_dialogs[path].view.get_buffer()
333+ self.assertTrue(buff is not None,
334+ 'buffer for metadata_view must not be None.')
335+
336+ expected = '\n'.join('%s: %s' % i for i in expected.iteritems())
337+ actual = buff.get_text(*buff.get_bounds())
338+ msg = 'buffer content must be %s (got %s instead).'
339+ self.assertEqual(actual, expected, msg % (expected, actual))
340+
341+ def test_metadata_are_disabled_until_started(self):
342+ """Metadata button is disabled until online."""
343 # disabled at startup
344 self.assert_widget_availability(enabled=False)
345
346@@ -1162,8 +1188,8 @@
347 self.do_start()
348 self.assert_widget_availability(enabled=True)
349
350- def test_raw_metadata_are_enabled_until_stopped(self):
351- """Raw metadata button is enabled until offline."""
352+ def test_metadata_are_enabled_until_stopped(self):
353+ """Metadata button is enabled until offline."""
354 self.do_connect()
355 self.assert_widget_availability(enabled=True)
356
357@@ -1183,12 +1209,12 @@
358 self.ui.on_stopped()
359 self.assert_widget_availability(enabled=False)
360
361- def test_raw_metadata_close_hides_the_dialog(self):
362- """Test raw_metadata close button emits RESPONSE_CLOSE when clicked."""
363- self.ui.raw_metadata_close.clicked()
364- self.assertFalse(self.ui.widget_is_visible(
365- self.ui.raw_metadata_dialog),
366- 'raw_metadata_dialog should not be visible.')
367+ def test_metadata_close_hides_the_dialog(self):
368+ """Test metadata close button emits RESPONSE_CLOSE when clicked."""
369+ dialog = self.ui._new_metadata_dialog(self.path)
370+ dialog.close.clicked()
371+ visible = self.ui.widget_is_visible(dialog)
372+ self.assertFalse(visible, 'metadata_dialog should not be visible.')
373
374 def test_file_chooser_open_emits_response_ok(self):
375 """Test volume close button emits RESPONSE_CLOSE when clicked."""
376@@ -1203,14 +1229,10 @@
377 self.assertEqual(gtk.FILE_CHOOSER_ACTION_OPEN, self.response,
378 'open button should emit FILE_CHOOSER_ACTION_OPEN.')
379
380- def test_on_raw_metadata_clicked(self):
381- """Test on_raw_metadata_clicked."""
382+ def test_on_metadata_clicked(self):
383+ """Test on_metadata_clicked."""
384 self.ui._u1_root = os.path.dirname(self.path)
385
386- self.assertFalse(self.ui.widget_is_visible(
387- self.ui.raw_metadata_dialog),
388- 'raw_metadata_dialog should not be visible.')
389-
390 self.ui.file_chooser.set_filename(self.path)
391
392 def test_file_chooser():
393@@ -1220,34 +1242,37 @@
394
395 gobject.timeout_add(100, test_and_click,
396 (self.ui.file_chooser_open, test_file_chooser))
397- self.ui.on_raw_metadata_clicked(self.ui.raw_metadata)
398+ self.ui.on_metadata_clicked(self.ui.metadata)
399+
400+ # dialog must exist now
401+ dialog = self.ui.metadata_dialogs[self.path]
402
403 self.assertFalse(self.ui.widget_is_visible(self.ui.file_chooser),
404 'file_chooser must be visible after metadata clicked.')
405 self.assertEqual(self.path, self.ui.file_chooser.get_filename(),
406 'filename returned by file chooser must be correct.')
407
408- # raw_metadata_dialog is enabled and shows the loading animation
409+ # metadata_dialog is enabled and shows the loading animation
410 self.assert_dialog_visibility(dialog=True, text_view=False, image=True)
411- expected = self.ui.raw_metadata_image.get_animation()
412+ expected = dialog.image.get_animation()
413 self.assertEqual(self.ui.loading_animation, expected,
414- 'raw_metadata_image must have the correct animation.')
415+ 'metadata_image must have the correct animation.')
416
417 # Check that the metadata was asked to the SD
418- self.assertEqual(self.ui.sd._meta_path, self.path)
419+ self.assertEqual(1, len(self.ui.sd._meta_paths))
420+ self.assertEqual(self.ui.sd._meta_paths[0], self.path)
421 # SD will eventually callback us with the metadata
422 self.ui.on_metadata_ready(self.path, self.metadata)
423
424- # raw_metadata_dialog is enabled and shows the metadata
425+ # metadata_dialog is enabled and shows the metadata
426 self.assert_dialog_visibility(dialog=True, text_view=True, image=False)
427
428 # user closes the dialog
429- self.ui.raw_metadata_close.clicked()
430+ dialog.close.clicked()
431
432 # dialog was closed already
433- self.assertFalse(self.ui.widget_is_visible(
434- self.ui.raw_metadata_dialog),
435- 'raw_metadata_dialog should not be visible.')
436+ visible = self.ui.widget_is_visible(dialog)
437+ self.assertFalse(visible, 'metadata_dialog should not be visible.')
438
439 def test_file_chooser_folder_is_u1root_when_visible(self):
440 """File chooser folder is ~/Ubuntu One only when visible."""
441@@ -1256,19 +1281,20 @@
442 "shouldn't have U1 folder before becoming visible")
443
444 gobject.timeout_add(100, self.ui.file_chooser_open.clicked)
445- self.ui.on_raw_metadata_clicked(self.ui.raw_metadata)
446+ self.ui.file_chooser.run()
447
448 self.assertEqual(self.ui.file_chooser.get_current_folder(),
449 UBUNTU_ONE_ROOT,
450 'should have U1 folder after becoming visible')
451
452- def test_raw_metadata_dialog_properties(self):
453- """The raw_metadata dialog has correct properties."""
454- title = self.name.replace('_', ' ').capitalize()
455- self.assert_dialog_properties(dialog_name='raw_metadata_dialog',
456- title=title, modal=False)
457+ def test_metadata_dialog_properties(self):
458+ """The metadata dialog has correct properties."""
459+ title = '%s for %s' % (self.name.replace('_', ' ').capitalize(),
460+ self.path)
461+ dialog = self.ui._new_metadata_dialog(self.path)
462+ self.assert_dialog_properties(dialog=dialog, title=title, modal=False)
463
464- actual = self.ui.raw_metadata_view.get_wrap_mode()
465+ actual = dialog.view.get_wrap_mode()
466 msg = 'wrap mode for view must be gtk.WRAP_WORD (got %s instead).'
467 self.assertEqual(gtk.WRAP_WORD, actual, msg % actual)
468
469@@ -1288,51 +1314,83 @@
470 self.patch(self.ui.sd, 'get_metadata', self.set_called)
471 gobject.timeout_add(100, test_and_click,
472 (self.ui.file_chooser_cancel, NO_OP))
473- self.ui.on_raw_metadata_clicked(self.ui.raw_metadata)
474+ self.ui.on_metadata_clicked(self.ui.metadata)
475
476 self.assertFalse(self.called,
477 'get_metadata should not be called if no file chosen.')
478
479 def test_filename_is_stored_if_open_clicked(self):
480- """Filename is stored as 'last_metadata_path' if user clicked open."""
481- self.assertTrue(self.ui.last_metadata_path is None,
482- 'last_metadata_path must be None.')
483+ """Filename is stored in the metadata dicts if user clicked open."""
484+ self.assertEqual(self.ui.metadata_dialogs, {},
485+ 'dialogs must be empty.')
486 self.ui._u1_root = os.path.dirname(self.path)
487 self.ui.file_chooser.set_filename(self.path)
488 gobject.timeout_add(100, test_and_click,
489 (self.ui.file_chooser_open, NO_OP))
490- self.ui.on_raw_metadata_clicked(self.ui.raw_metadata)
491+ self.ui.on_metadata_clicked(self.ui.metadata)
492
493- self.assertEqual(self.path, self.ui.last_metadata_path,
494- 'last_metadata_path should be what the user choose.')
495+ self.assertEqual([self.path], self.ui.metadata_dialogs.keys(),
496+ 'metadata dict keys should be what the user choose.')
497
498 def test_on_metadata_ready(self):
499- """Callback on_metadata_ready updates the raw_metadata_view."""
500+ """Callback on_metadata_ready updates the metadata_view."""
501 path = 'bla'
502- self.ui.last_metadata_path = path
503+ self.ui.metadata_dialogs = {path: self.ui._new_metadata_dialog(path)}
504 self.ui.on_metadata_ready(path, self.metadata)
505
506- buff = self.ui.raw_metadata_view.get_buffer()
507- self.assertTrue(buff is not None,
508- 'buffer for raw_metadata_view must not be None.')
509-
510- expected = '\n'.join('%s: %s' % i for i in self.metadata.iteritems())
511- actual = buff.get_text(*buff.get_bounds())
512- msg = 'buffer content must be %s (got %s instead).'
513- self.assertEqual(actual, expected,
514- msg % (expected, actual))
515+ self.assert_buffer_content(path, self.metadata)
516
517 def test_on_metadata_ready_doesnt_update_if_last_path_doesnt_match(self):
518- """Callback on_metadata_ready updates the raw_metadata_view."""
519- self.patch(self.ui.raw_metadata_view.get_buffer(),
520- 'set_text', self.set_called)
521+ """Callback on_metadata_ready updates the metadata_view."""
522+ self.patch(self.ui, '_new_metadata_dialog', self.set_called)
523 path = 'bla'
524- self.ui.last_metadata_path = path + path
525+ assert path not in self.ui.metadata_dialogs
526 self.ui.on_metadata_ready(path, self.metadata)
527
528 self.assertFalse(self.called,
529 'view should not be updated if key is not last one.')
530
531+ def test_two_metadata_windows(self):
532+ """More than one metadata window is allowed."""
533+ self.patch(self.ui.file_chooser, 'run',
534+ lambda: gtk.FILE_CHOOSER_ACTION_OPEN)
535+
536+ path1 = os.path.abspath(self.mktemp())
537+ open(path1, 'w').close()
538+ assert os.path.exists(path1)
539+ meta1 = {'value': 'Lorem ipsum dolor sit amet.'}
540+
541+ path2 = os.path.abspath(self.mktemp())
542+ open(path2, 'w').close()
543+ assert os.path.exists(path2)
544+ meta2 = {'value': 'Etiam iaculis congue nisl.'}
545+
546+ self.ui.file_chooser.get_filename = lambda: path1
547+ self.ui.on_metadata_clicked(self.ui.metadata)
548+
549+ self.ui.file_chooser.get_filename = lambda: path2
550+ self.ui.on_metadata_clicked(self.ui.metadata)
551+
552+ # Check that the UI has 2 metadata dialogs
553+ self.assertTrue(2, len(self.ui.metadata_dialogs))
554+
555+ # Check that the metadata was asked to the SD
556+ self.assertEqual(2, len(self.ui.sd._meta_paths))
557+ self.assertEqual(self.ui.sd._meta_paths[0], path1)
558+ self.assertEqual(self.ui.sd._meta_paths[1], path2)
559+
560+ # SD will eventually callback us with the metadata
561+ self.ui.on_metadata_ready(path1, meta1)
562+ # SD will eventually callback us with the metadata
563+ self.ui.on_metadata_ready(path2, meta2)
564+
565+ self.assert_buffer_content(path1, meta1)
566+ self.assert_buffer_content(path2, meta2)
567+
568+ # user closes the dialog
569+ self.ui.metadata_dialogs[path1].close.clicked()
570+ self.ui.metadata_dialogs[path2].close.clicked()
571+
572
573 def override_input_output(input_args, output_args):
574 """Call 'f' but receive fixed input and return fixed output."""
575
576=== modified file 'pylintrc'
577--- pylintrc 2010-07-16 00:48:22 +0000
578+++ pylintrc 2010-08-01 14:53:41 +0000
579@@ -57,7 +57,8 @@
580
581 # Disable the message(s) with the given id(s).
582 W0108: Lambda may not be necessary
583-disable-msg=W0142, W0613, W0108
584+R0923: Interface not implemented
585+disable-msg=W0142, W0613, W0108, R0923
586
587
588 [REPORTS]

Subscribers

People subscribed via source and target branches

to all changes: