Merge lp:~mvo/software-center/apptreeview-tweaks into lp:software-center

Proposed by Michael Vogt
Status: Merged
Merged at revision: 2829
Proposed branch: lp:~mvo/software-center/apptreeview-tweaks
Merge into: lp:software-center
Diff against target: 802 lines (+234/-254)
8 files modified
softwarecenter/db/application.py (+2/-0)
softwarecenter/testutils.py (+7/-0)
softwarecenter/ui/gtk3/models/appstore2.py (+43/-71)
softwarecenter/ui/gtk3/panes/installedpane.py (+15/-6)
softwarecenter/ui/gtk3/views/appview.py (+78/-18)
softwarecenter/ui/gtk3/widgets/apptreeview.py (+33/-75)
test/gtk3/test_app_view.py (+56/-12)
test/gtk3/test_appview.py (+0/-72)
To merge this branch: bzr merge lp:~mvo/software-center/apptreeview-tweaks
Reviewer Review Type Date Requested Status
Gary Lasker (community) Approve
Review via email: mp+96593@code.launchpad.net

Description of the change

This branch gets rid of the
"""
 AttributeError: 'TreeModelFilter' object has no attribute 'load_range' bug
"""
errors when navigating to the installed pane. But in order to fix that I had to look around for quite a bit
and did some refactor/cleanup along the way and added profile data and some more fixes:
- move the logic for appname into the db as far as possible
- merge _AppPropertiesHelper and AppPropertiesHelper
- fix a missing self.hide_appview_spinner() that prevented the installed pane to show up quicker
- add some profile data
- make the testcode in appview.py show a List and the testcode in apptreeview.py show a test treeview
- merge test_app_view.py and test_appview.py

To post a comment you must log in.
2796. By Michael Vogt

pyflake fixes

Revision history for this message
Gary Lasker (gary-lasker) wrote :

These are very nice changes indeed. Thank you, Michael!!

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'softwarecenter/db/application.py'
2--- softwarecenter/db/application.py 2012-02-16 09:52:24 +0000
3+++ softwarecenter/db/application.py 2012-03-08 15:25:23 +0000
4@@ -103,6 +103,8 @@
5 if doc:
6 appname = db.get_appname(doc)
7 if appname:
8+ if db.is_appname_duplicated(appname):
9+ appname = "%s (%s)" % (appname, db.get_pkgname(doc))
10 return appname
11 else:
12 return db.get_summary(doc)
13
14=== modified file 'softwarecenter/testutils.py'
15--- softwarecenter/testutils.py 2012-03-01 10:13:53 +0000
16+++ softwarecenter/testutils.py 2012-03-08 15:25:23 +0000
17@@ -102,6 +102,13 @@
18 import softwarecenter.paths
19 return softwarecenter.paths.datadir
20
21+def get_test_categories(db):
22+ import softwarecenter.paths
23+ from softwarecenter.db.categories import CategoriesParser
24+ parser = CategoriesParser(db)
25+ cats = parser.parse_applications_menu(softwarecenter.paths.APP_INSTALL_PATH)
26+ return cats
27+
28 def get_test_enquirer_matches(db, query=None, limit=20, sortmode=0):
29 from softwarecenter.db.enquire import AppEnquire
30 import xapian
31
32=== modified file 'softwarecenter/ui/gtk3/models/appstore2.py'
33--- softwarecenter/ui/gtk3/models/appstore2.py 2012-01-05 11:24:20 +0000
34+++ softwarecenter/ui/gtk3/models/appstore2.py 2012-03-08 15:25:23 +0000
35@@ -31,7 +31,6 @@
36 from softwarecenter.utils import ExecutionTime, SimpleFileDownloader, split_icon_ext
37 from softwarecenter.backend import get_install_backend
38 from softwarecenter.backend.reviews import get_review_loader
39-from softwarecenter.db.database import Application
40 from softwarecenter.paths import SOFTWARE_CENTER_ICON_CACHE_DIR
41
42 import softwarecenter.paths
43@@ -74,7 +73,7 @@
44 return
45
46
47-class _AppPropertiesHelper(GObject.GObject):
48+class AppPropertiesHelper(GObject.GObject):
49 """ Baseclass that contains common functions for our
50 liststore/treestore, only useful for subclassing
51 """
52@@ -86,8 +85,30 @@
53 ),
54 }
55
56- def __init__(self):
57+ def __init__(self, db, cache, icons, icon_size=48, global_icon_cache=False):
58 GObject.GObject.__init__(self)
59+ self.db = db
60+ self.cache = cache
61+
62+ # get all categories
63+ cat_parser = CategoriesParser(db)
64+ self.all_categories = cat_parser.parse_applications_menu(
65+ softwarecenter.paths.APP_INSTALL_PATH)
66+
67+ # reviews stats loader
68+ self.review_loader = get_review_loader(cache, db)
69+
70+ # icon jazz
71+ self.icons = icons
72+ self.icon_size = icon_size
73+
74+ # cache the 'missing icon' used in the treeview for apps without an icon
75+ self._missing_icon = icons.load_icon(Icons.MISSING_APP, icon_size, 0)
76+ if global_icon_cache:
77+ self.icon_cache = _app_icon_cache
78+ else:
79+ self.icon_cache = {}
80+ return
81
82 def _download_icon_and_show_when_ready(self, url, pkgname, icon_file_name):
83 LOG.debug("did not find the icon locally, must download %s" % icon_file_name)
84@@ -138,31 +159,23 @@
85 return self.db.get_pkgname(doc)
86
87 def get_application(self, doc):
88- appname = doc.get_value(XapianValues.APPNAME)
89- pkgname = self.db.get_pkgname(doc)
90- # TODO: requests
91- return Application(appname, pkgname, "")
92+ return self.db.get_application(doc)
93
94 def get_appname(self, doc):
95- appname = doc.get_value(XapianValues.APPNAME)
96- if not appname:
97- appname = self.db.get_summary(doc)
98- else:
99- if self.db.is_appname_duplicated(appname):
100- appname = "%s (%s)" % (appname, self.get_pkgname(doc))
101- return appname
102+ app = self.db.get_application(doc)
103+ return app.get_display_name(self.db, doc)
104
105 def get_markup(self, doc):
106- appname = doc.get_value(XapianValues.APPNAME)
107+ app = self.db.get_application(doc)
108
109- if not appname:
110+ # the logic is that "apps" are displayed normally
111+ # but "packages" are displayed with their summary as name
112+ if app.appname:
113+ appname = self.get_appname(doc)
114+ summary = self.db.get_summary(doc)
115+ else:
116 appname = self.db.get_summary(doc)
117 summary = self.get_pkgname(doc)
118- else:
119- if self.db.is_appname_duplicated(appname):
120- appname = "%s (%s)" % (appname, self.get_pkgname(doc))
121-
122- summary = self.db.get_summary(doc)
123
124 return "%s\n<small>%s</small>" % (
125 GObject.markup_escape_text(appname),
126@@ -239,44 +252,14 @@
127 else:
128 return ''
129
130-class AppPropertiesHelper(_AppPropertiesHelper):
131-
132- def __init__(self, db, cache, icons, icon_size=48, global_icon_cache=False):
133- super(AppPropertiesHelper, self).__init__()
134- self.db = db
135- self.cache = cache
136-
137- cat_parser = CategoriesParser(db)
138- self.all_categories = cat_parser.parse_applications_menu(
139- softwarecenter.paths.APP_INSTALL_PATH)
140-
141- # reviews stats loader
142- self.review_loader = get_review_loader(cache, db)
143-
144- # icon jazz
145- self.icons = icons
146- self.icon_size = icon_size
147- # cache the 'missing icon' used in the treeview for apps without an icon
148- self._missing_icon = icons.load_icon(Icons.MISSING_APP,
149- icon_size, 0)
150-
151- if global_icon_cache:
152- self.icon_cache = _app_icon_cache
153- else:
154- self.icon_cache = {}
155- return
156-
157 def get_icon_at_size(self, doc, width, height):
158 pixbuf = self.get_icon(doc)
159 pixbuf = pixbuf.scale_simple(width, height,
160 GdkPixbuf.InterpType.BILINEAR)
161 return pixbuf
162
163- def get_transaction_progress(self, doc):
164- raise NotImplemented
165-
166-
167-class AppGenericStore(_AppPropertiesHelper):
168+
169+class AppGenericStore(AppPropertiesHelper):
170
171 # column types
172 COL_TYPES = (GObject.TYPE_PYOBJECT,)
173@@ -291,12 +274,8 @@
174 LOAD_INITIAL = 75
175
176 def __init__(self, db, cache, icons, icon_size, global_icon_cache):
177- # the usual suspects
178- self.db = db
179- self.cache = cache
180-
181- # reviews stats loader
182- self.review_loader = get_review_loader(cache, db)
183+ AppPropertiesHelper.__init__(self, db, cache, icons, icon_size,
184+ global_icon_cache)
185
186 # backend stuff
187 self.backend = get_install_backend()
188@@ -307,21 +286,9 @@
189 # keep track of paths for transactions in progress
190 self.transaction_path_map = {}
191
192- # icon jazz
193- self.icons = icons
194- self.icon_size = icon_size
195-
196- if global_icon_cache:
197- self.icon_cache = _app_icon_cache
198- else:
199- self.icon_cache = {}
200-
201 # active row path
202 self.active_row = None
203
204- # cache the 'missing icon' used in the treeview for apps without an icon
205- self._missing_icon = icons.load_icon(Icons.MISSING_APP, icon_size, 0)
206-
207 self._in_progress = False
208 self._break = False
209
210@@ -396,6 +363,10 @@
211 GObject.idle_add(buffer_icons)
212 return
213
214+ def load_range(self, indices, step):
215+ # stub
216+ return
217+
218 class AppListStore(Gtk.ListStore, AppGenericStore):
219 """ use for flat applist views. for large lists this appends rows approx
220 three times faster than the AppTreeStore equivalent
221@@ -526,3 +497,4 @@
222 self.transaction_path_map = {}
223 Gtk.TreeStore.clear(self)
224 return
225+
226
227=== modified file 'softwarecenter/ui/gtk3/panes/installedpane.py'
228--- softwarecenter/ui/gtk3/panes/installedpane.py 2012-03-06 18:19:33 +0000
229+++ softwarecenter/ui/gtk3/panes/installedpane.py 2012-03-08 15:25:23 +0000
230@@ -30,7 +30,8 @@
231
232 from softwarecenter.enums import (NonAppVisibility,
233 SortMethods)
234-from softwarecenter.utils import wait_for_apt_cache_ready, utf8
235+from softwarecenter.utils import (
236+ wait_for_apt_cache_ready, utf8, ExecutionTime)
237 from softwarecenter.db.categories import (CategoriesParser,
238 categories_sorted_by_name)
239 from softwarecenter.ui.gtk3.models.appstore2 import (
240@@ -209,6 +210,8 @@
241 # hacky, hide the header
242 self.app_view.header_hbox.hide()
243
244+ self.hide_appview_spinner()
245+
246 # now we are initialized
247 self.emit("installed-pane-created")
248
249@@ -313,6 +316,10 @@
250 model = self.base_model # base model not treefilter
251 model.clear()
252
253+ def profiled_rebuild_categorised_view():
254+ with ExecutionTime("rebuild_categorized_view"):
255+ rebuild_categorised_view()
256+
257 def rebuild_categorised_view():
258 self.cat_docid_map = {}
259 enq = self.enquirer
260@@ -324,6 +331,7 @@
261
262 xfilter = AppFilter(self.db, self.cache)
263 xfilter.set_installed_only(True)
264+
265 for cat in self._all_cats:
266 # for each category do category query and append as a new
267 # node to tree_view
268@@ -379,9 +387,6 @@
269 # hide the local spinner
270 self.hide_installed_view_spinner()
271
272- # hide the main spinner (if it's showing)
273- self.hide_appview_spinner()
274-
275 if window:
276 window.set_cursor(None)
277
278@@ -392,7 +397,7 @@
279 self.emit("app-list-changed", i)
280 return
281
282- GObject.idle_add(rebuild_categorised_view)
283+ GObject.idle_add(profiled_rebuild_categorised_view)
284 return
285
286 def _build_oneconfview(self):
287@@ -407,6 +412,10 @@
288 model = self.base_model # base model not treefilter
289 model.clear()
290
291+ def profiled_rebuild_oneconfview():
292+ with ExecutionTime("rebuild_oneconfview"):
293+ rebuild_oneconfview()
294+
295 def rebuild_oneconfview():
296
297 # FIXME for P: hide the search entry
298@@ -487,7 +496,7 @@
299 self.emit("app-list-changed", i)
300 return
301
302- GObject.idle_add(rebuild_oneconfview)
303+ GObject.idle_add(profiled_rebuild_oneconfview)
304 return
305
306 def _check_expand(self):
307
308=== modified file 'softwarecenter/ui/gtk3/views/appview.py'
309--- softwarecenter/ui/gtk3/views/appview.py 2012-03-07 06:02:07 +0000
310+++ softwarecenter/ui/gtk3/views/appview.py 2012-03-08 15:25:23 +0000
311@@ -16,20 +16,18 @@
312 # this program; if not, write to the Free Software Foundation, Inc.,
313 # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
314
315-#~ from __future__ import with_statement
316
317 import logging
318
319 from gi.repository import Gtk, GObject
320 from gettext import gettext as _
321-#~ import gettext
322
323 from softwarecenter.enums import SortMethods
324 from softwarecenter.ui.gtk3.em import StockEms
325 from softwarecenter.ui.gtk3.models.appstore2 import AppTreeStore
326 from softwarecenter.ui.gtk3.widgets.apptreeview import AppTreeView
327 from softwarecenter.ui.gtk3.models.appstore2 import AppPropertiesHelper
328-#~ from softwarecenter.ui.gtk3.widgets.containers import FlowableGrid
329+from softwarecenter.utils import ExecutionTime
330
331 LOG=logging.getLogger(__name__)
332
333@@ -191,10 +189,10 @@
334 # ... also we dont currently support user sorting in the
335 # installedview, so issue is somewhat moot for the time being...
336 if isinstance(self.tree_view.appmodel, AppTreeStore):
337+ LOG.debug("display_matches called on AppTreeStore, ignoring")
338 return
339
340 sort_by_relevance = is_search and not self.user_defined_sort_method
341-
342 if sort_by_relevance:
343 self._use_combobox_with_sort_by_search_ranking()
344 self.set_sort_method_with_no_signal(self._SORT_BY_SEARCH_RANKING)
345@@ -257,30 +255,91 @@
346 py+self.tree_view.selected_row_renderer.icon_y_offset)
347
348
349+
350+
351+
352+# ----------------------------------------------- testcode
353+from softwarecenter.enums import NonAppVisibility
354+
355+def get_query_from_search_entry(search_term):
356+ import xapian
357+ if not search_term:
358+ return xapian.Query("")
359+ parser = xapian.QueryParser()
360+ user_query = parser.parse_query(search_term)
361+ return user_query
362+
363+def on_entry_changed(widget, data):
364+
365+ def _work():
366+ new_text = widget.get_text()
367+ (view, enquirer) = data
368+
369+ with ExecutionTime("total time"):
370+ with ExecutionTime("enquire.set_query()"):
371+ enquirer.set_query(get_query_from_search_entry(new_text),
372+ limit=100*1000,
373+ nonapps_visible=NonAppVisibility.ALWAYS_VISIBLE)
374+
375+ store = view.tree_view.get_model()
376+ with ExecutionTime("store.clear()"):
377+ store.clear()
378+
379+ with ExecutionTime("store.set_from_matches()"):
380+ store.set_from_matches(enquirer.matches)
381+
382+ with ExecutionTime("model settle (size=%s)" % len(store)):
383+ while Gtk.events_pending():
384+ Gtk.main_iteration()
385+ return
386+
387+ if widget.stamp:
388+ GObject.source_remove(widget.stamp)
389+ widget.stamp = GObject.timeout_add(250, _work)
390+
391 def get_test_window():
392+ import softwarecenter.log
393+ softwarecenter.log.root.setLevel(level=logging.DEBUG)
394+ softwarecenter.log.add_filters_from_string("performance")
395+ fmt = logging.Formatter("%(name)s - %(message)s", None)
396+ softwarecenter.log.handler.setFormatter(fmt)
397+
398 from softwarecenter.testutils import (
399- get_test_db, get_test_pkg_info, get_test_gtk3_icon_cache,
400- get_test_enquirer_matches)
401+ get_test_db, get_test_pkg_info, get_test_gtk3_icon_cache)
402 from softwarecenter.ui.gtk3.models.appstore2 import AppListStore
403
404 db = get_test_db()
405 cache = get_test_pkg_info()
406 icons = get_test_gtk3_icon_cache()
407
408- # create the view
409- appview = AppView(db, cache, icons, show_ratings=True)
410- liststore = AppListStore(db, cache, icons)
411- appview.set_model(liststore)
412-
413- # do a simple query and display that
414- appview.display_matches(get_test_enquirer_matches(db))
415-
416- # and put it in the window
417+ # create a filter
418+ from softwarecenter.db.appfilter import AppFilter
419+ filter = AppFilter(db, cache)
420+ filter.set_supported_only(False)
421+ filter.set_installed_only(True)
422+
423+ # appview
424+ from softwarecenter.db.enquire import AppEnquire
425+ enquirer = AppEnquire(cache, db)
426+ store = AppListStore(db, cache, icons)
427+
428+ from softwarecenter.ui.gtk3.views.appview import AppView
429+ view = AppView(db, cache, icons, show_ratings=True)
430+ view.set_model(store)
431+
432+ entry = Gtk.Entry()
433+ entry.stamp = 0
434+ entry.connect("changed", on_entry_changed, (view, enquirer))
435+
436+ box = Gtk.VBox()
437+ box.pack_start(entry, False, True, 0)
438+ box.pack_start(view, True, True, 0)
439+
440 win = Gtk.Window()
441- win.add(appview)
442- win.set_data("appview", appview)
443-
444+ win.set_data("appview", view)
445+ win.set_data("entry", entry)
446 win.connect("destroy", lambda x: Gtk.main_quit())
447+ win.add(box)
448 win.set_size_request(600, 400)
449 win.show_all()
450
451@@ -288,4 +347,5 @@
452
453 if __name__ == "__main__":
454 win = get_test_window()
455+ win.get_data("entry").set_text("gtk3")
456 Gtk.main()
457
458=== modified file 'softwarecenter/ui/gtk3/widgets/apptreeview.py'
459--- softwarecenter/ui/gtk3/widgets/apptreeview.py 2012-03-07 06:02:07 +0000
460+++ softwarecenter/ui/gtk3/widgets/apptreeview.py 2012-03-08 15:25:23 +0000
461@@ -1,7 +1,5 @@
462 from gi.repository import Gtk, Gdk, GObject
463 import logging
464-import os
465-import xapian
466
467 from gettext import gettext as _
468
469@@ -13,7 +11,7 @@
470 CellButtonIDs)
471
472 from softwarecenter.ui.gtk3.em import em, StockEms
473-from softwarecenter.enums import (AppActions, NonAppVisibility, Icons)
474+from softwarecenter.enums import (AppActions, Icons)
475 from softwarecenter.utils import ExecutionTime
476 from softwarecenter.backend import get_install_backend
477 from softwarecenter.netstatus import (get_network_watcher,
478@@ -168,7 +166,8 @@
479 return None
480
481 def get_rowref(self, model, path):
482- if path == None: return None
483+ if path == None:
484+ return None
485 return model[path][AppGenericStore.COL_ROW_DATA]
486
487 def rowref_is_category(self, rowref):
488@@ -469,6 +468,12 @@
489
490 path = model.get_path(it)
491
492+ # this will give us the right underlying model regardless if its
493+ # a TreeModelFilter, a AppTreeStore or a AppListStore
494+ model = self.appmodel
495+
496+ # this will pre-load data *only* on a AppListStore, it has
497+ # no effect with a AppTreeStore
498 if model[path][0] is None:
499 indices = path.get_indices()
500 model.load_range(indices, 5)
501@@ -586,41 +591,6 @@
502 return self.get_path_at_pos(x, y)[0] == self.get_cursor()[0]
503
504
505-def get_query_from_search_entry(search_term):
506- if not search_term:
507- return xapian.Query("")
508- parser = xapian.QueryParser()
509- user_query = parser.parse_query(search_term)
510- return user_query
511-
512-def on_entry_changed(widget, data):
513-
514- def _work():
515- new_text = widget.get_text()
516- (view, enquirer) = data
517-
518- with ExecutionTime("total time"):
519- with ExecutionTime("enquire.set_query()"):
520- enquirer.set_query(get_query_from_search_entry(new_text),
521- limit=100*1000,
522- nonapps_visible=NonAppVisibility.ALWAYS_VISIBLE)
523-
524- store = view.tree_view.get_model()
525- with ExecutionTime("store.clear()"):
526- store.clear()
527-
528- with ExecutionTime("store.set_documents()"):
529- store.set_from_matches(enquirer.matches)
530-
531- with ExecutionTime("model settle (size=%s)" % len(store)):
532- while Gtk.events_pending():
533- Gtk.main_iteration()
534- return
535-
536- if widget.stamp: GObject.source_remove(widget.stamp)
537- widget.stamp = GObject.timeout_add(250, _work)
538-
539-
540
541 def get_test_window():
542 import softwarecenter.log
543@@ -629,24 +599,13 @@
544 fmt = logging.Formatter("%(name)s - %(message)s", None)
545 softwarecenter.log.handler.setFormatter(fmt)
546
547- from softwarecenter.paths import XAPIAN_BASE_PATH
548- xapian_base_path = XAPIAN_BASE_PATH
549- pathname = os.path.join(xapian_base_path, "xapian")
550-
551- # the store
552- from softwarecenter.db.pkginfo import get_pkg_info
553- cache = get_pkg_info()
554- cache.open()
555-
556- # the db
557- from softwarecenter.db.database import StoreDatabase
558- db = StoreDatabase(pathname, cache)
559- db.open()
560-
561- # additional icons come from app-install-data
562- icons = Gtk.IconTheme.get_default()
563- icons.prepend_search_path("/usr/share/app-install/icons/")
564- icons.prepend_search_path("/usr/share/software-center/icons/")
565+ from softwarecenter.testutils import (
566+ get_test_db, get_test_pkg_info, get_test_gtk3_icon_cache,
567+ get_test_categories)
568+
569+ cache = get_test_pkg_info()
570+ db = get_test_db()
571+ icons = get_test_gtk3_icon_cache()
572
573 # create a filter
574 from softwarecenter.db.appfilter import AppFilter
575@@ -654,30 +613,29 @@
576 filter.set_supported_only(False)
577 filter.set_installed_only(True)
578
579- # appview
580- from softwarecenter.ui.gtk3.models.appstore2 import AppListStore
581- from softwarecenter.db.enquire import AppEnquire
582- enquirer = AppEnquire(cache, db)
583- store = AppListStore(db, cache, icons)
584+ # get the TREEstore
585+ from softwarecenter.ui.gtk3.models.appstore2 import AppTreeStore
586+ store = AppTreeStore(db, cache, icons)
587
588+ # populate from data
589+ cats = get_test_categories(db)
590+ for cat in cats[:3]:
591+ with ExecutionTime("query cat '%s'" % cat.name):
592+ docs = db.get_docs_from_query(cat.query)
593+ store.set_category_documents(cat, docs)
594+
595+ # ok, this is confusing - the AppView contains the AppTreeView that
596+ # is a tree or list depending on the model
597 from softwarecenter.ui.gtk3.views.appview import AppView
598- view = AppView(db, cache, icons, show_ratings=True)
599- view.set_model(store)
600-
601- entry = Gtk.Entry()
602- entry.stamp = 0
603- entry.connect("changed", on_entry_changed, (view, enquirer))
604- entry.set_text("gtk3")
605-
606- scroll = Gtk.ScrolledWindow()
607+ app_view = AppView(db, cache, icons, show_ratings=True)
608+ app_view.set_model(store)
609+
610 box = Gtk.VBox()
611- box.pack_start(entry, False, True, 0)
612- box.pack_start(scroll, True, True, 0)
613+ box.pack_start(app_view, True, True, 0)
614
615 win = Gtk.Window()
616+ win.add(box)
617 win.connect("destroy", lambda x: Gtk.main_quit())
618- scroll.add(view)
619- win.add(box)
620 win.set_size_request(600, 400)
621 win.show_all()
622
623
624=== modified file 'test/gtk3/test_app_view.py'
625--- test/gtk3/test_app_view.py 2012-01-16 14:42:49 +0000
626+++ test/gtk3/test_app_view.py 2012-03-08 15:25:23 +0000
627@@ -1,11 +1,8 @@
628 #!/usr/bin/python
629
630-import time
631 import unittest
632 import xapian
633
634-from gi.repository import Gtk
635-
636 from testutils import setup_test_env
637 setup_test_env()
638
639@@ -15,6 +12,7 @@
640 from softwarecenter.testutils import (get_test_db,
641 get_test_pkg_info,
642 get_test_gtk3_icon_cache,
643+ do_events,
644 )
645
646 class TestAppView(unittest.TestCase):
647@@ -39,7 +37,7 @@
648 # set matches
649 appview.clear_model()
650 appview.display_matches(enquirer.matches)
651- self._p()
652+ do_events()
653 # verify that the order is actually the correct one
654 model = appview.tree_view.get_model()
655 docs_in_model = [item[0] for item in model]
656@@ -49,15 +47,61 @@
657 for i in range(len(docs_in_model)):
658 self.assertEqual(self.db.get_pkgname(docs_in_model[i]),
659 self.db.get_pkgname(docs_from_enquirer[i]))
660-
661- def _p(self):
662- for i in range(5):
663- time.sleep(0.1)
664- while Gtk.events_pending():
665- Gtk.main_iteration()
666+ win.destroy()
667+
668+ def test_appview_search_combo(self):
669+ from softwarecenter.ui.gtk3.views.appview import get_test_window
670+ from softwarecenter.testutils import get_test_enquirer_matches
671+
672+ # test if combox sort option "by relevance" vanishes for non-searches
673+ # LP: #861778
674+ expected_normal = ["By Name", "By Top Rated", "By Newest First"]
675+ expected_search = ["By Name", "By Top Rated", "By Newest First",
676+ "By Relevance"]
677+
678+ # setup goo
679+ win = get_test_window()
680+ appview = win.get_data("appview")
681+ #entry = win.get_data("entry")
682+ do_events()
683+
684+ # get the model
685+ model = appview.sort_methods_combobox.get_model()
686+
687+ # test normal window (no search)
688+ matches = get_test_enquirer_matches(appview.helper.db)
689+ appview.display_matches(matches, is_search=False)
690+ do_events()
691+ in_model = []
692+ for item in model:
693+ in_model.append(model.get_value(item.iter, 0))
694+ self.assertEqual(in_model, expected_normal)
695+
696+ # now repeat and simulate a search
697+ matches = get_test_enquirer_matches(appview.helper.db)
698+ appview.display_matches(matches, is_search=True)
699+ do_events()
700+ in_model = []
701+ for item in model:
702+ in_model.append(model.get_value(item.iter, 0))
703+ self.assertEqual(in_model, expected_search)
704+
705+ # and back again to no search
706+ matches = get_test_enquirer_matches(appview.helper.db)
707+ appview.display_matches(matches, is_search=False)
708+ do_events()
709+ # collect items in the model
710+ in_model = []
711+ for item in model:
712+ in_model.append(model.get_value(item.iter, 0))
713+ self.assertEqual(expected_normal, in_model)
714+
715+ # destroy
716+ win.destroy()
717+
718
719
720 if __name__ == "__main__":
721- import logging
722- logging.basicConfig(level=logging.DEBUG)
723+ #import logging
724+ #logging.basicConfig(level=logging.DEBUG)
725 unittest.main()
726
727=== removed file 'test/gtk3/test_appview.py'
728--- test/gtk3/test_appview.py 2012-01-16 14:42:49 +0000
729+++ test/gtk3/test_appview.py 1970-01-01 00:00:00 +0000
730@@ -1,72 +0,0 @@
731-#!/usr/bin/python
732-
733-from gi.repository import Gtk, GObject
734-import time
735-import unittest
736-
737-from testutils import setup_test_env
738-setup_test_env()
739-
740-#from mock import Mock
741-
742-TIMEOUT=300
743-
744-class TestViews(unittest.TestCase):
745-
746- def test_appview_search_combo(self):
747- from softwarecenter.ui.gtk3.views.appview import get_test_window
748- from softwarecenter.testutils import get_test_enquirer_matches
749-
750- # test if combox sort option "by relevance" vanishes for non-searches
751- # LP: #861778
752- expected_normal = ["By Name", "By Top Rated", "By Newest First"]
753- expected_search = ["By Name", "By Top Rated", "By Newest First",
754- "By Relevance"]
755-
756- # setup goo
757- win = get_test_window()
758- self._p()
759- appview = win.get_data("appview")
760-
761- # test normal window (no search)
762- model = appview.sort_methods_combobox.get_model()
763- # collect items in the model
764- in_model = []
765- for item in model:
766- in_model.append(model.get_value(item.iter, 0))
767- # this is what we expect there
768- self.assertEqual(expected_normal, in_model)
769-
770- # now repeat and simulate a search
771- matches = get_test_enquirer_matches(appview.helper.db)
772- appview.display_matches(matches, is_search=True)
773- self._p()
774- in_model = []
775- for item in model:
776- in_model.append(model.get_value(item.iter, 0))
777- self.assertEqual(in_model, expected_search)
778-
779- # and back again to no search
780- matches = get_test_enquirer_matches(appview.helper.db)
781- appview.display_matches(matches, is_search=False)
782- self._p()
783- # collect items in the model
784- in_model = []
785- for item in model:
786- in_model.append(model.get_value(item.iter, 0))
787- self.assertEqual(expected_normal, in_model)
788-
789- # destroy
790- GObject.timeout_add(TIMEOUT, lambda: win.destroy())
791- Gtk.main()
792-
793- def _p(self):
794- for i in range(10):
795- time.sleep(0.1)
796- while Gtk.events_pending():
797- Gtk.main_iteration()
798-
799-if __name__ == "__main__":
800- import logging
801- logging.basicConfig(level=logging.DEBUG)
802- unittest.main()

Subscribers

People subscribed via source and target branches