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
=== modified file 'data/ui/gui.glade'
--- data/ui/gui.glade 2010-07-18 20:58:35 +0000
+++ data/ui/gui.glade 2010-08-01 14:53:41 +0000
@@ -256,13 +256,13 @@
256 </packing>256 </packing>
257 </child>257 </child>
258 <child>258 <child>
259 <object class="GtkToolButton" id="raw_metadata">259 <object class="GtkToolButton" id="metadata">
260 <property name="visible">True</property>260 <property name="visible">True</property>
261 <property name="sensitive">False</property>261 <property name="sensitive">False</property>
262 <property name="label" translatable="yes">Metadata</property>262 <property name="label" translatable="yes">Metadata</property>
263 <property name="use_underline">True</property>263 <property name="use_underline">True</property>
264 <property name="stock_id">gtk-find</property>264 <property name="stock_id">gtk-find</property>
265 <signal name="clicked" handler="on_raw_metadata_clicked"/>265 <signal name="clicked" handler="on_metadata_clicked"/>
266 </object>266 </object>
267 <packing>267 <packing>
268 <property name="expand">False</property>268 <property name="expand">False</property>
@@ -980,6 +980,7 @@
980 </object>980 </object>
981 <object class="GtkFileChooserDialog" id="file_chooser">981 <object class="GtkFileChooserDialog" id="file_chooser">
982 <property name="border_width">5</property>982 <property name="border_width">5</property>
983 <property name="window_position">center</property>
983 <property name="type_hint">normal</property>984 <property name="type_hint">normal</property>
984 <property name="has_separator">False</property>985 <property name="has_separator">False</property>
985 <property name="create_folders">False</property>986 <property name="create_folders">False</property>
986987
=== modified file 'magicicada/__init__.py'
--- magicicada/__init__.py 2010-07-18 20:58:35 +0000
+++ magicicada/__init__.py 2010-08-01 14:53:41 +0000
@@ -57,6 +57,13 @@
57 logger.addHandler(console)57 logger.addHandler(console)
5858
5959
60# Instance of 'A' has no 'y' member
61# pylint: disable-msg=E1101
62
63# Unused argument, we need them for GTK callbacks
64# pylint: disable-msg=W0613
65
66
60class MagicicadaUI(object):67class MagicicadaUI(object):
61 """Magicicada GUI main class."""68 """Magicicada GUI main class."""
6269
@@ -97,8 +104,7 @@
97 'shares_to_me_view', 'shares_to_me_store', 'shares_to_me_close',104 'shares_to_me_view', 'shares_to_me_store', 'shares_to_me_close',
98 'shares_to_others', 'shares_to_others_dialog', # shares_to_others105 'shares_to_others', 'shares_to_others_dialog', # shares_to_others
99 'shares_to_others_view', 'shares_to_others_store',106 'shares_to_others_view', 'shares_to_others_store',
100 'shares_to_others_close',107 'shares_to_others_close', 'metadata', # metadata
101 'raw_metadata', # raw metadata
102 'is_started', 'is_connected', 'is_online', # status bar images108 'is_started', 'is_connected', 'is_online', # status bar images
103 'status_label', 'status_icon', # status label and systray icon109 'status_label', 'status_icon', # status label and systray icon
104 'metaq_view', 'contentq_view', # queues tree views110 'metaq_view', 'contentq_view', # queues tree views
@@ -117,7 +123,7 @@
117 self._make_view_sortable('shares_to_me')123 self._make_view_sortable('shares_to_me')
118 self._make_view_sortable('shares_to_others')124 self._make_view_sortable('shares_to_others')
119125
120 self.raw_metadata_dialog = self._new_metadata_dialog()126 self.metadata_dialogs = {}
121 self.volumes = (self.folders, self.shares_to_me, self.shares_to_others)127 self.volumes = (self.folders, self.shares_to_me, self.shares_to_others)
122 self.windows = (self.main_window, self.about_dialog,128 self.windows = (self.main_window, self.about_dialog,
123 self.folders_dialog)129 self.folders_dialog)
@@ -146,7 +152,6 @@
146 self.widget_is_visible = lambda w: w.get_property('visible')152 self.widget_is_visible = lambda w: w.get_property('visible')
147 self.widget_enabled = lambda w: self.widget_is_visible(w) and \153 self.widget_enabled = lambda w: self.widget_is_visible(w) and \
148 w.is_sensitive()154 w.is_sensitive()
149 self.last_metadata_path = None
150 self.update()155 self.update()
151156
152 def _make_view_sortable(self, view_name):157 def _make_view_sortable(self, view_name):
@@ -159,23 +164,24 @@
159 col.connect('clicked', self.on_store_sort_column_changed, i, store)164 col.connect('clicked', self.on_store_sort_column_changed, i, store)
160 self._sorting_order[store][i] = gtk.SORT_ASCENDING165 self._sorting_order[store][i] = gtk.SORT_ASCENDING
161166
162 def _new_metadata_dialog(self):167 def _new_metadata_dialog(self, path):
163 """Return a new metadata dialog."""168 """Return a new metadata dialog."""
164 dialog = gtk.Dialog(title='Raw metadata', parent=self.main_window,169 dialog = gtk.Dialog(title='Metadata for %s' % path,
170 parent=self.main_window,
165 flags=gtk.DIALOG_NO_SEPARATOR,171 flags=gtk.DIALOG_NO_SEPARATOR,
166 buttons=(gtk.STOCK_CLOSE, gtk.RESPONSE_CLOSE))172 buttons=(gtk.STOCK_CLOSE, gtk.RESPONSE_CLOSE))
167 dialog.set_size_request(600, 300)173 dialog.set_size_request(600, 300)
168 dialog.set_position(gtk.WIN_POS_CENTER)174 # gtk.WIN_POS_CENTER makes dialog overlap
169 setattr(self, 'raw_metadata_dialog', dialog)175 dialog.set_position(gtk.WIN_POS_MOUSE)
170176
171 close_button = dialog.action_area.get_children()[-1]177 close_button = dialog.action_area.get_children()[-1]
172 close_button.connect('clicked', self.on_raw_metadata_close_clicked)178 close_button.connect('clicked', self.on_metadata_close_clicked, path)
173 close_button.connect('activate', self.on_raw_metadata_close_clicked)179 close_button.connect('activate', self.on_metadata_close_clicked, path)
174 setattr(self, 'raw_metadata_close', close_button)180 dialog.close = close_button
175181
176 image = gtk.Image()182 image = gtk.Image()
177 image.set_from_animation(self.loading_animation)183 image.set_from_animation(self.loading_animation)
178 setattr(self, 'raw_metadata_image', image)184 dialog.image = image
179185
180 dialog.get_child().add(image)186 dialog.get_child().add(image)
181187
@@ -183,9 +189,9 @@
183 text_view.set_editable(False)189 text_view.set_editable(False)
184 text_view.set_wrap_mode(gtk.WRAP_WORD)190 text_view.set_wrap_mode(gtk.WRAP_WORD)
185 dialog.get_child().add(text_view)191 dialog.get_child().add(text_view)
186 setattr(self, 'raw_metadata_view', text_view)192 dialog.view = text_view
187193
188 dialog.hide() # XXX to be fixed later194 self.metadata_dialogs[path] = dialog
189 return dialog195 return dialog
190196
191 # GTK callbacks197 # GTK callbacks
@@ -215,7 +221,7 @@
215 """Stop syncdaemon."""221 """Stop syncdaemon."""
216 for v in self.volumes:222 for v in self.volumes:
217 v.set_sensitive(False)223 v.set_sensitive(False)
218 self.raw_metadata.set_sensitive(False)224 self.metadata.set_sensitive(False)
219225
220 if self.widget_enabled(self.disconnect):226 if self.widget_enabled(self.disconnect):
221 self.on_disconnect_clicked(self.disconnect)227 self.on_disconnect_clicked(self.disconnect)
@@ -301,26 +307,28 @@
301307
302 def on_file_chooser_show(self, widget, data=None):308 def on_file_chooser_show(self, widget, data=None):
303 """Close the file_chooser dialog."""309 """Close the file_chooser dialog."""
304 if self.last_metadata_path is None:310 #if self.last_metadata_path is None:
305 self.file_chooser.set_current_folder(self._u1_root)311 self.file_chooser.set_current_folder(self._u1_root)
306312
307 def on_raw_metadata_close_clicked(self, widget, data=None):313 def on_metadata_close_clicked(self, widget, path):
308 """Close the raw_metadata dialog."""314 """Close the metadata dialog."""
309 self.raw_metadata_dialog.hide()315 self.metadata_dialogs[path].destroy()
310316
311 def on_raw_metadata_clicked(self, widget, data=None):317 def on_metadata_clicked(self, widget, data=None):
312 """Show raw metadata for a path choosen by the user."""318 """Show metadata for a path choosen by the user."""
313 res = self.file_chooser.run()319 res = self.file_chooser.run()
314 self.file_chooser.hide()320 self.file_chooser.hide()
315 if res != gtk.FILE_CHOOSER_ACTION_OPEN:321 if res != gtk.FILE_CHOOSER_ACTION_OPEN:
316 return322 return
317323
318 self.last_metadata_path = self.file_chooser.get_filename()324 path = self.file_chooser.get_filename()
319 self.sd.get_metadata(path=self.last_metadata_path)325 assert path is not None
320 self.raw_metadata_view.hide()326 dialog = self._new_metadata_dialog(path)
321 self.raw_metadata_image.show()327 self.sd.get_metadata(path)
322 self._start_loading(self.raw_metadata_image)328 dialog.view.hide()
323 self.raw_metadata_dialog.show()329 dialog.image.show()
330 self._start_loading(dialog.image)
331 dialog.show()
324332
325 def on_status_icon_activate(self, widget, data=None):333 def on_status_icon_activate(self, widget, data=None):
326 """Systray icon was clicked."""334 """Systray icon was clicked."""
@@ -362,7 +370,7 @@
362370
363 for v in self.volumes:371 for v in self.volumes:
364 v.set_sensitive(True)372 v.set_sensitive(True)
365 self.raw_metadata.set_sensitive(True)373 self.metadata.set_sensitive(True)
366374
367 self._update_queues_and_status(self.sd.current_state)375 self._update_queues_and_status(self.sd.current_state)
368376
@@ -457,14 +465,15 @@
457 @log(logger)465 @log(logger)
458 def on_metadata_ready(self, path, metadata):466 def on_metadata_ready(self, path, metadata):
459 """Lower layer has the requested metadata for 'path'."""467 """Lower layer has the requested metadata for 'path'."""
460 logger.debug('on_metadata_ready: path: %r, last_metadata_path: %r',468 logger.debug('on_metadata_ready: path: %r', path)
461 path, self.last_metadata_path)469 if path not in self.metadata_dialogs:
462 if path != self.last_metadata_path:
463 return470 return
464 self.raw_metadata_image.hide()471
465 self.raw_metadata_view.show()472 dialog = self.metadata_dialogs[path]
473 dialog.image.hide()
474 dialog.view.show()
466 text = '\n'.join('%s: %s' % i for i in metadata.iteritems())475 text = '\n'.join('%s: %s' % i for i in metadata.iteritems())
467 self.raw_metadata_view.get_buffer().set_text(text)476 dialog.view.get_buffer().set_text(text)
468477
469 # custom478 # custom
470479
471480
=== modified file 'magicicada/tests/test_magicicada.py'
--- magicicada/tests/test_magicicada.py 2010-07-28 21:48:34 +0000
+++ magicicada/tests/test_magicicada.py 2010-08-01 14:53:41 +0000
@@ -39,9 +39,16 @@
3939
40# It's ok to access private data in the test suite40# It's ok to access private data in the test suite
41# pylint: disable-msg=W021241# pylint: disable-msg=W0212
42
42# Arguments number differs from overridden method43# Arguments number differs from overridden method
43# pylint: disable-msg=W022144# pylint: disable-msg=W0221
4445
46# Instance of 'A' has no 'y' member
47# pylint: disable-msg=E1101
48
49# Instance of 'A' has no 'y' member (but some types could not be inferred)
50# pylint: disable-msg=E1103
51
4552
46def process_gtk_pendings():53def process_gtk_pendings():
47 """Process all gtk pending events."""54 """Process all gtk pending events."""
@@ -74,7 +81,7 @@
74 """A faked syncdaemon."""81 """A faked syncdaemon."""
7582
76 def __init__(self):83 def __init__(self):
77 self._meta_path = None84 self._meta_paths = []
7885
79 self.current_state = syncdaemon.State()86 self.current_state = syncdaemon.State()
80 self.meta_queue = []87 self.meta_queue = []
@@ -100,7 +107,7 @@
100 'is_connected', True)107 'is_connected', True)
101 self.disconnect = lambda: \108 self.disconnect = lambda: \
102 setattr(self.current_state, 'is_connected', False)109 setattr(self.current_state, 'is_connected', False)
103 self.get_metadata = lambda path: setattr(self, '_meta_path', path)110 self.get_metadata = lambda path: self._meta_paths.append(path)
104111
105112
106class MagicicadaUITestCase(TestCase):113class MagicicadaUITestCase(TestCase):
@@ -220,10 +227,12 @@
220 self.assertTrue(sensitive if enabled else not sensitive,227 self.assertTrue(sensitive if enabled else not sensitive,
221 msg % (widget_name, '' if enabled else 'not '))228 msg % (widget_name, '' if enabled else 'not '))
222229
223 def assert_dialog_properties(self, dialog_name, title, size=(600, 300),230 def assert_dialog_properties(self, dialog_name=None, title=None,
224 modal=True):231 size=(600, 300), modal=True, dialog=None):
225 """The dialog 'dialog_name' has correct properties."""232 """The dialog 'dialog_name' has correct properties."""
226 dialog = getattr(self.ui, dialog_name)233 assert (dialog_name is None) ^ (dialog is None)
234 if dialog is None:
235 dialog = getattr(self.ui, dialog_name)
227 actual = dialog.size_request()236 actual = dialog.size_request()
228 msg = 'size must be %s (got %s instead).'237 msg = 'size must be %s (got %s instead).'
229 self.assertEquals(size, actual, msg % (size, actual))238 self.assertEquals(size, actual, msg % (size, actual))
@@ -233,8 +242,10 @@
233 msg % (dialog_name, '' if modal else 'not '))242 msg % (dialog_name, '' if modal else 'not '))
234243
235 position = dialog.get_property('window-position')244 position = dialog.get_property('window-position')
236 self.assertEqual(gtk.WIN_POS_CENTER, position,245 expected = gtk.WIN_POS_CENTER if dialog_name is not None else \
237 '%s must be centered.' % dialog_name)246 gtk.WIN_POS_MOUSE
247 msg = 'dialog must have %s position (got %s instead).'
248 self.assertEqual(expected, position, msg % (expected, position))
238249
239 actual = dialog.get_title()250 actual = dialog.get_title()
240 msg = '%s title must be %s (got %s instead)'251 msg = '%s title must be %s (got %s instead)'
@@ -1046,14 +1057,14 @@
1046 def test_volume_sorting(self):1057 def test_volume_sorting(self):
1047 """Test volume panel can be re-sorted."""1058 """Test volume panel can be re-sorted."""
1048 for i, col in enumerate(self.volume_view.get_columns()):1059 for i, col in enumerate(self.volume_view.get_columns()):
1049 col.clicked() # click on the column1060 col.clicked() # click on the column
1050 self.assert_sort_order_correct(col, i, gtk.SORT_ASCENDING)1061 self.assert_sort_order_correct(col, i, gtk.SORT_ASCENDING)
1051 self.assert_sort_indicator_correct(col)1062 self.assert_sort_indicator_correct(col)
10521063
1053 col.clicked() # click on the column, sort order must change1064 col.clicked() # click on the column, sort order must change
1054 self.assert_sort_order_correct(col, i, gtk.SORT_DESCENDING)1065 self.assert_sort_order_correct(col, i, gtk.SORT_DESCENDING)
10551066
1056 col.clicked() # click again, sort order must be the first one1067 col.clicked() # click again, sort order must be the first one
1057 self.assert_sort_order_correct(col, i, gtk.SORT_ASCENDING)1068 self.assert_sort_order_correct(col, i, gtk.SORT_ASCENDING)
10581069
10591070
@@ -1125,7 +1136,7 @@
1125class MagicicadaUIMetadataTestCase(MagicicadaUITestCase):1136class MagicicadaUIMetadataTestCase(MagicicadaUITestCase):
1126 """UI test cases for metadata display."""1137 """UI test cases for metadata display."""
11271138
1128 name = 'raw_metadata'1139 name = 'metadata'
11291140
1130 def setUp(self):1141 def setUp(self):
1131 """Init."""1142 """Init."""
@@ -1138,23 +1149,38 @@
1138 s = super(MagicicadaUIMetadataTestCase, self)1149 s = super(MagicicadaUIMetadataTestCase, self)
1139 s.assert_widget_availability(self.name, enabled)1150 s.assert_widget_availability(self.name, enabled)
11401151
1141 def assert_dialog_visibility(self, dialog, text_view, image):1152 def assert_dialog_visibility(self, dialog, text_view, image, path=None):
1142 """Check the visibility for dialog, text_view and image."""1153 """Check the visibility for dialog, text_view and image."""
1154 if path is None:
1155 path = self.path
1156
1143 msg = '%s visibility should be %s (got %s instead).'1157 msg = '%s visibility should be %s (got %s instead).'
1144 visible = self.ui.widget_is_visible(self.ui.raw_metadata_dialog)1158 metadata_dialog = self.ui.metadata_dialogs[path]
1159 visible = self.ui.widget_is_visible(metadata_dialog)
1145 self.assertEqual(dialog, visible,1160 self.assertEqual(dialog, visible,
1146 msg % ('raw_metadata_dialog', dialog, visible))1161 msg % ('metadata_dialog', dialog, visible))
11471162
1148 visible = self.ui.widget_is_visible(self.ui.raw_metadata_view)1163 visible = self.ui.widget_is_visible(metadata_dialog.view)
1149 self.assertEqual(text_view, visible,1164 self.assertEqual(text_view, visible,
1150 msg % ('raw_metadata_view', text_view, visible))1165 msg % ('metadata_view', text_view, visible))
11511166
1152 visible = self.ui.widget_is_visible(self.ui.raw_metadata_image)1167 visible = self.ui.widget_is_visible(metadata_dialog.image)
1153 self.assertEqual(image, visible,1168 self.assertEqual(image, visible,
1154 msg % ('raw_metadata_image', image, visible))1169 msg % ('metadata_image', image, visible))
11551170
1156 def test_raw_metadata_are_disabled_until_started(self):1171 def assert_buffer_content(self, path, expected):
1157 """Raw metadata button is disabled until online."""1172 """Check that the buffer content is correct for 'path'."""
1173 buff = self.ui.metadata_dialogs[path].view.get_buffer()
1174 self.assertTrue(buff is not None,
1175 'buffer for metadata_view must not be None.')
1176
1177 expected = '\n'.join('%s: %s' % i for i in expected.iteritems())
1178 actual = buff.get_text(*buff.get_bounds())
1179 msg = 'buffer content must be %s (got %s instead).'
1180 self.assertEqual(actual, expected, msg % (expected, actual))
1181
1182 def test_metadata_are_disabled_until_started(self):
1183 """Metadata button is disabled until online."""
1158 # disabled at startup1184 # disabled at startup
1159 self.assert_widget_availability(enabled=False)1185 self.assert_widget_availability(enabled=False)
11601186
@@ -1162,8 +1188,8 @@
1162 self.do_start()1188 self.do_start()
1163 self.assert_widget_availability(enabled=True)1189 self.assert_widget_availability(enabled=True)
11641190
1165 def test_raw_metadata_are_enabled_until_stopped(self):1191 def test_metadata_are_enabled_until_stopped(self):
1166 """Raw metadata button is enabled until offline."""1192 """Metadata button is enabled until offline."""
1167 self.do_connect()1193 self.do_connect()
1168 self.assert_widget_availability(enabled=True)1194 self.assert_widget_availability(enabled=True)
11691195
@@ -1183,12 +1209,12 @@
1183 self.ui.on_stopped()1209 self.ui.on_stopped()
1184 self.assert_widget_availability(enabled=False)1210 self.assert_widget_availability(enabled=False)
11851211
1186 def test_raw_metadata_close_hides_the_dialog(self):1212 def test_metadata_close_hides_the_dialog(self):
1187 """Test raw_metadata close button emits RESPONSE_CLOSE when clicked."""1213 """Test metadata close button emits RESPONSE_CLOSE when clicked."""
1188 self.ui.raw_metadata_close.clicked()1214 dialog = self.ui._new_metadata_dialog(self.path)
1189 self.assertFalse(self.ui.widget_is_visible(1215 dialog.close.clicked()
1190 self.ui.raw_metadata_dialog),1216 visible = self.ui.widget_is_visible(dialog)
1191 'raw_metadata_dialog should not be visible.')1217 self.assertFalse(visible, 'metadata_dialog should not be visible.')
11921218
1193 def test_file_chooser_open_emits_response_ok(self):1219 def test_file_chooser_open_emits_response_ok(self):
1194 """Test volume close button emits RESPONSE_CLOSE when clicked."""1220 """Test volume close button emits RESPONSE_CLOSE when clicked."""
@@ -1203,14 +1229,10 @@
1203 self.assertEqual(gtk.FILE_CHOOSER_ACTION_OPEN, self.response,1229 self.assertEqual(gtk.FILE_CHOOSER_ACTION_OPEN, self.response,
1204 'open button should emit FILE_CHOOSER_ACTION_OPEN.')1230 'open button should emit FILE_CHOOSER_ACTION_OPEN.')
12051231
1206 def test_on_raw_metadata_clicked(self):1232 def test_on_metadata_clicked(self):
1207 """Test on_raw_metadata_clicked."""1233 """Test on_metadata_clicked."""
1208 self.ui._u1_root = os.path.dirname(self.path)1234 self.ui._u1_root = os.path.dirname(self.path)
12091235
1210 self.assertFalse(self.ui.widget_is_visible(
1211 self.ui.raw_metadata_dialog),
1212 'raw_metadata_dialog should not be visible.')
1213
1214 self.ui.file_chooser.set_filename(self.path)1236 self.ui.file_chooser.set_filename(self.path)
12151237
1216 def test_file_chooser():1238 def test_file_chooser():
@@ -1220,34 +1242,37 @@
12201242
1221 gobject.timeout_add(100, test_and_click,1243 gobject.timeout_add(100, test_and_click,
1222 (self.ui.file_chooser_open, test_file_chooser))1244 (self.ui.file_chooser_open, test_file_chooser))
1223 self.ui.on_raw_metadata_clicked(self.ui.raw_metadata)1245 self.ui.on_metadata_clicked(self.ui.metadata)
1246
1247 # dialog must exist now
1248 dialog = self.ui.metadata_dialogs[self.path]
12241249
1225 self.assertFalse(self.ui.widget_is_visible(self.ui.file_chooser),1250 self.assertFalse(self.ui.widget_is_visible(self.ui.file_chooser),
1226 'file_chooser must be visible after metadata clicked.')1251 'file_chooser must be visible after metadata clicked.')
1227 self.assertEqual(self.path, self.ui.file_chooser.get_filename(),1252 self.assertEqual(self.path, self.ui.file_chooser.get_filename(),
1228 'filename returned by file chooser must be correct.')1253 'filename returned by file chooser must be correct.')
12291254
1230 # raw_metadata_dialog is enabled and shows the loading animation1255 # metadata_dialog is enabled and shows the loading animation
1231 self.assert_dialog_visibility(dialog=True, text_view=False, image=True)1256 self.assert_dialog_visibility(dialog=True, text_view=False, image=True)
1232 expected = self.ui.raw_metadata_image.get_animation()1257 expected = dialog.image.get_animation()
1233 self.assertEqual(self.ui.loading_animation, expected,1258 self.assertEqual(self.ui.loading_animation, expected,
1234 'raw_metadata_image must have the correct animation.')1259 'metadata_image must have the correct animation.')
12351260
1236 # Check that the metadata was asked to the SD1261 # Check that the metadata was asked to the SD
1237 self.assertEqual(self.ui.sd._meta_path, self.path)1262 self.assertEqual(1, len(self.ui.sd._meta_paths))
1263 self.assertEqual(self.ui.sd._meta_paths[0], self.path)
1238 # SD will eventually callback us with the metadata1264 # SD will eventually callback us with the metadata
1239 self.ui.on_metadata_ready(self.path, self.metadata)1265 self.ui.on_metadata_ready(self.path, self.metadata)
12401266
1241 # raw_metadata_dialog is enabled and shows the metadata1267 # metadata_dialog is enabled and shows the metadata
1242 self.assert_dialog_visibility(dialog=True, text_view=True, image=False)1268 self.assert_dialog_visibility(dialog=True, text_view=True, image=False)
12431269
1244 # user closes the dialog1270 # user closes the dialog
1245 self.ui.raw_metadata_close.clicked()1271 dialog.close.clicked()
12461272
1247 # dialog was closed already1273 # dialog was closed already
1248 self.assertFalse(self.ui.widget_is_visible(1274 visible = self.ui.widget_is_visible(dialog)
1249 self.ui.raw_metadata_dialog),1275 self.assertFalse(visible, 'metadata_dialog should not be visible.')
1250 'raw_metadata_dialog should not be visible.')
12511276
1252 def test_file_chooser_folder_is_u1root_when_visible(self):1277 def test_file_chooser_folder_is_u1root_when_visible(self):
1253 """File chooser folder is ~/Ubuntu One only when visible."""1278 """File chooser folder is ~/Ubuntu One only when visible."""
@@ -1256,19 +1281,20 @@
1256 "shouldn't have U1 folder before becoming visible")1281 "shouldn't have U1 folder before becoming visible")
12571282
1258 gobject.timeout_add(100, self.ui.file_chooser_open.clicked)1283 gobject.timeout_add(100, self.ui.file_chooser_open.clicked)
1259 self.ui.on_raw_metadata_clicked(self.ui.raw_metadata)1284 self.ui.file_chooser.run()
12601285
1261 self.assertEqual(self.ui.file_chooser.get_current_folder(),1286 self.assertEqual(self.ui.file_chooser.get_current_folder(),
1262 UBUNTU_ONE_ROOT,1287 UBUNTU_ONE_ROOT,
1263 'should have U1 folder after becoming visible')1288 'should have U1 folder after becoming visible')
12641289
1265 def test_raw_metadata_dialog_properties(self):1290 def test_metadata_dialog_properties(self):
1266 """The raw_metadata dialog has correct properties."""1291 """The metadata dialog has correct properties."""
1267 title = self.name.replace('_', ' ').capitalize()1292 title = '%s for %s' % (self.name.replace('_', ' ').capitalize(),
1268 self.assert_dialog_properties(dialog_name='raw_metadata_dialog',1293 self.path)
1269 title=title, modal=False)1294 dialog = self.ui._new_metadata_dialog(self.path)
1295 self.assert_dialog_properties(dialog=dialog, title=title, modal=False)
12701296
1271 actual = self.ui.raw_metadata_view.get_wrap_mode()1297 actual = dialog.view.get_wrap_mode()
1272 msg = 'wrap mode for view must be gtk.WRAP_WORD (got %s instead).'1298 msg = 'wrap mode for view must be gtk.WRAP_WORD (got %s instead).'
1273 self.assertEqual(gtk.WRAP_WORD, actual, msg % actual)1299 self.assertEqual(gtk.WRAP_WORD, actual, msg % actual)
12741300
@@ -1288,51 +1314,83 @@
1288 self.patch(self.ui.sd, 'get_metadata', self.set_called)1314 self.patch(self.ui.sd, 'get_metadata', self.set_called)
1289 gobject.timeout_add(100, test_and_click,1315 gobject.timeout_add(100, test_and_click,
1290 (self.ui.file_chooser_cancel, NO_OP))1316 (self.ui.file_chooser_cancel, NO_OP))
1291 self.ui.on_raw_metadata_clicked(self.ui.raw_metadata)1317 self.ui.on_metadata_clicked(self.ui.metadata)
12921318
1293 self.assertFalse(self.called,1319 self.assertFalse(self.called,
1294 'get_metadata should not be called if no file chosen.')1320 'get_metadata should not be called if no file chosen.')
12951321
1296 def test_filename_is_stored_if_open_clicked(self):1322 def test_filename_is_stored_if_open_clicked(self):
1297 """Filename is stored as 'last_metadata_path' if user clicked open."""1323 """Filename is stored in the metadata dicts if user clicked open."""
1298 self.assertTrue(self.ui.last_metadata_path is None,1324 self.assertEqual(self.ui.metadata_dialogs, {},
1299 'last_metadata_path must be None.')1325 'dialogs must be empty.')
1300 self.ui._u1_root = os.path.dirname(self.path)1326 self.ui._u1_root = os.path.dirname(self.path)
1301 self.ui.file_chooser.set_filename(self.path)1327 self.ui.file_chooser.set_filename(self.path)
1302 gobject.timeout_add(100, test_and_click,1328 gobject.timeout_add(100, test_and_click,
1303 (self.ui.file_chooser_open, NO_OP))1329 (self.ui.file_chooser_open, NO_OP))
1304 self.ui.on_raw_metadata_clicked(self.ui.raw_metadata)1330 self.ui.on_metadata_clicked(self.ui.metadata)
13051331
1306 self.assertEqual(self.path, self.ui.last_metadata_path,1332 self.assertEqual([self.path], self.ui.metadata_dialogs.keys(),
1307 'last_metadata_path should be what the user choose.')1333 'metadata dict keys should be what the user choose.')
13081334
1309 def test_on_metadata_ready(self):1335 def test_on_metadata_ready(self):
1310 """Callback on_metadata_ready updates the raw_metadata_view."""1336 """Callback on_metadata_ready updates the metadata_view."""
1311 path = 'bla'1337 path = 'bla'
1312 self.ui.last_metadata_path = path1338 self.ui.metadata_dialogs = {path: self.ui._new_metadata_dialog(path)}
1313 self.ui.on_metadata_ready(path, self.metadata)1339 self.ui.on_metadata_ready(path, self.metadata)
13141340
1315 buff = self.ui.raw_metadata_view.get_buffer()1341 self.assert_buffer_content(path, self.metadata)
1316 self.assertTrue(buff is not None,
1317 'buffer for raw_metadata_view must not be None.')
1318
1319 expected = '\n'.join('%s: %s' % i for i in self.metadata.iteritems())
1320 actual = buff.get_text(*buff.get_bounds())
1321 msg = 'buffer content must be %s (got %s instead).'
1322 self.assertEqual(actual, expected,
1323 msg % (expected, actual))
13241342
1325 def test_on_metadata_ready_doesnt_update_if_last_path_doesnt_match(self):1343 def test_on_metadata_ready_doesnt_update_if_last_path_doesnt_match(self):
1326 """Callback on_metadata_ready updates the raw_metadata_view."""1344 """Callback on_metadata_ready updates the metadata_view."""
1327 self.patch(self.ui.raw_metadata_view.get_buffer(),1345 self.patch(self.ui, '_new_metadata_dialog', self.set_called)
1328 'set_text', self.set_called)
1329 path = 'bla'1346 path = 'bla'
1330 self.ui.last_metadata_path = path + path1347 assert path not in self.ui.metadata_dialogs
1331 self.ui.on_metadata_ready(path, self.metadata)1348 self.ui.on_metadata_ready(path, self.metadata)
13321349
1333 self.assertFalse(self.called,1350 self.assertFalse(self.called,
1334 'view should not be updated if key is not last one.')1351 'view should not be updated if key is not last one.')
13351352
1353 def test_two_metadata_windows(self):
1354 """More than one metadata window is allowed."""
1355 self.patch(self.ui.file_chooser, 'run',
1356 lambda: gtk.FILE_CHOOSER_ACTION_OPEN)
1357
1358 path1 = os.path.abspath(self.mktemp())
1359 open(path1, 'w').close()
1360 assert os.path.exists(path1)
1361 meta1 = {'value': 'Lorem ipsum dolor sit amet.'}
1362
1363 path2 = os.path.abspath(self.mktemp())
1364 open(path2, 'w').close()
1365 assert os.path.exists(path2)
1366 meta2 = {'value': 'Etiam iaculis congue nisl.'}
1367
1368 self.ui.file_chooser.get_filename = lambda: path1
1369 self.ui.on_metadata_clicked(self.ui.metadata)
1370
1371 self.ui.file_chooser.get_filename = lambda: path2
1372 self.ui.on_metadata_clicked(self.ui.metadata)
1373
1374 # Check that the UI has 2 metadata dialogs
1375 self.assertTrue(2, len(self.ui.metadata_dialogs))
1376
1377 # Check that the metadata was asked to the SD
1378 self.assertEqual(2, len(self.ui.sd._meta_paths))
1379 self.assertEqual(self.ui.sd._meta_paths[0], path1)
1380 self.assertEqual(self.ui.sd._meta_paths[1], path2)
1381
1382 # SD will eventually callback us with the metadata
1383 self.ui.on_metadata_ready(path1, meta1)
1384 # SD will eventually callback us with the metadata
1385 self.ui.on_metadata_ready(path2, meta2)
1386
1387 self.assert_buffer_content(path1, meta1)
1388 self.assert_buffer_content(path2, meta2)
1389
1390 # user closes the dialog
1391 self.ui.metadata_dialogs[path1].close.clicked()
1392 self.ui.metadata_dialogs[path2].close.clicked()
1393
13361394
1337def override_input_output(input_args, output_args):1395def override_input_output(input_args, output_args):
1338 """Call 'f' but receive fixed input and return fixed output."""1396 """Call 'f' but receive fixed input and return fixed output."""
13391397
=== modified file 'pylintrc'
--- pylintrc 2010-07-16 00:48:22 +0000
+++ pylintrc 2010-08-01 14:53:41 +0000
@@ -57,7 +57,8 @@
5757
58# Disable the message(s) with the given id(s).58# Disable the message(s) with the given id(s).
59W0108: Lambda may not be necessary59W0108: Lambda may not be necessary
60disable-msg=W0142, W0613, W010860R0923: Interface not implemented
61disable-msg=W0142, W0613, W0108, R0923
6162
6263
63[REPORTS]64[REPORTS]

Subscribers

People subscribed via source and target branches

to all changes: