Source

pytest-gui / pytest_gui / gtkui / runstate.py

Full commit
import gtk
from pygtkhelpers.delegates import SlaveView
from pygtkhelpers.ui.objectlist import ObjectList, Column
from .filefails import FileFailView


class FileEntry(object):
    view = None

    def __init__(self, filename):
        self.filename = filename
        self.reports = []
        self.interesting = False

    def add_report(self, report):
        self.reports.append(report)
        if self.view is not None:
            self.view.collection.append(report)
        if report.outcome not in ('passed', 'skipped'):
            self.interesting = True


class RunStateView(SlaveView):

    def __init__(self, master):
        self.master = master
        SlaveView.__init__(self)

    def create_ui(self):
        self.hbox = gtk.HBox()

        self.run_tests = gtk.Button("Run All")
        self.run_failed_tests = gtk.Button("Run Failed")
        self.back_to_collect = gtk.Button("Change Selection")
        self.hbox.add(self.run_tests)
        self.hbox.add(self.run_failed_tests)
        self.hbox.add(self.back_to_collect)

        self.widget.pack_start(self.hbox, expand=False)

        self.run_stat_label = gtk.Label()
        self.widget.pack_start(self.run_stat_label, expand=False)

        self.file_listing = ObjectList([
            Column('filename'),
        ])
        self.file_listing.set_visible_func(
            #XXX: figure why x is none sometimes
            lambda x: x is not None and x.interesting,
        )
        self.widget.add(self.file_listing)
        self.file_fail_view = FileFailView()

    def set_tests(self, test_ids):
        self.test_ids = test_ids
        self.stats = {}
        self.file_tests = {}
        self.file_listing.clear()
        for test_id in test_ids:
            if '::' in test_id:
                file, item = test_id.split('::', 1)
            else:
                #XXX: from pytest-pep8
                file = test_id
                item = None
            self.file_tests.setdefault(file, []).append(item)

        self.file_enries = {}
        for file in sorted(self.file_tests):
            entry = FileEntry(file)
            self.file_enries[file] = entry
            self.file_listing.append(entry)

    def update(self):
        executed = sum(len(x) for x in self.stats.values())
        stats = [
            '%s/%s executed' % (executed, len(self.test_ids)),
        ]

        for stat in ('passed', 'failed', 'skipped', 'xfailed', 'xpassed'):
            if stat in self.stats:
                stats.append(str(len(self.stats['failed'])))
                stats.append(stat)
        self.run_stat_label.set_text(' '.join(stats))
        #XXX: update the ui
        pass

    def on_file_listing__item_activated(self, _, item):
        self.file_fail_view.set_entry(item)
        self.file_fail_view.show()

    def handle_report(self, report):
        file = report.nodeid.split('::')[0]
        entry = self.file_enries[file]
        entry.add_report(report)
        self.file_listing.update(entry)
        self.stats.setdefault(report.outcome, []).append(report)
        self.update()

    def report_start(self, item):
        pass

    def report_result(self, item):
        self.handle_report(item.report)
        pass

    def on_run_failed_tests__clicked(self, _):
        #XXX: this will run all tests by accident if there are no failed
        #XXX: xpass/..?
        self.master.run_once(test_ids=self.stats['failed'])

    def on_run_tests__clicked(self, _):
        self.master.run_once(test_ids=self.test_ids)

    def on_back_to_collect__clicked(self, _):
        self.master.run_once(collectonly=True)