~andrewsomething/exaile/karmic

« back to all changes in this revision

Viewing changes to tools/guitest/gtktest.py

  • Committer: Aren Olson
  • Date: 2009-09-12 00:36:59 UTC
  • Revision ID: reacocard@gmail.com-20090912003659-w373sg0n04uoa8op
remove useless files, add soem of the fixes from lp bug 420019

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
"""Objects that help unit-test pyGTK applications."""
2
 
 
3
 
import unittest
4
 
 
5
 
import gtk
6
 
import gtk.glade
7
 
 
8
 
from guitest.utils import GuiTestHelperMixin, DoctestHelper
9
 
from guitest.state import guistate
10
 
 
11
 
 
12
 
#
13
 
# Stubbed GTK global functions
14
 
#
15
 
 
16
 
def pygtk_require(version):
17
 
    pass
18
 
 
19
 
 
20
 
def gtk_main():
21
 
    mainhook = guistate.main
22
 
    if mainhook is None:
23
 
        raise ValueError("mainhook not specified!")
24
 
    else:
25
 
        guistate.main = None # try to avoid infinite recursion
26
 
        guistate.level += 1
27
 
        mainhook()
28
 
 
29
 
 
30
 
def gtk_main_quit():
31
 
    guistate.level -= 1
32
 
 
33
 
 
34
 
def gtk_main_level():
35
 
    return guistate.level
36
 
 
37
 
 
38
 
def gtk_main_iteration(block=True):
39
 
    return False
40
 
 
41
 
 
42
 
#
43
 
# Some mutilated GTK classes to suppress side effects
44
 
#
45
 
 
46
 
 
47
 
class _InvisibleWidgetMixin(object):
48
 
    """A mixin that can be used to try to stop widgets from appearing onscreen.
49
 
 
50
 
    Its attribute `_visible` (None by default) is set to True if the widget's
51
 
    show() method or friends are called, False if hide() or friends are called.
52
 
    """
53
 
 
54
 
    _visible = None
55
 
 
56
 
    def show(self):
57
 
        self._visible = True
58
 
 
59
 
    def hide(self):
60
 
        self._visible = False
61
 
 
62
 
    show_now = show
63
 
    show_all = show
64
 
    hide_all = hide
65
 
 
66
 
 
67
 
class gtk_Window(_InvisibleWidgetMixin, gtk.Window):
68
 
    pass
69
 
 
70
 
 
71
 
class _StubbedDialogMixin(_InvisibleWidgetMixin):
72
 
    """A mixin that simulates a response to a dialog.
73
 
 
74
 
    Normally when a dialog's run() method is called, the application will
75
 
    block.  This mixin runs the dialog handler provided in the unit test
76
 
    code instead of waiting for input from the user.
77
 
    """
78
 
 
79
 
    def run(self):
80
 
        """Run the dialog and return a user-specified value.
81
 
 
82
 
        Invokes callable guistate.dlg_handler with the dialog instance
83
 
        as a single argument and returns the handler's return value as
84
 
        the response.
85
 
        """
86
 
        assert guistate.dlg_handler, 'dlg_handler not set'
87
 
        handler = guistate.dlg_handler
88
 
        guistate.dlg_handler = None
89
 
        response = handler(self)
90
 
        assert response is not None, 'dlg_handler returned None'
91
 
        return response
92
 
 
93
 
 
94
 
# Find and override out gtk.Dialog and all its subclasses
95
 
 
96
 
dialog_overrides = {}
97
 
 
98
 
_gtk_attrs = dir(gtk)
99
 
try:
100
 
    _gtk_attrs.remove('_gobject') # avoid a deprecation warning
101
 
except ValueError:
102
 
    pass # the attribute may be removed in the future
103
 
 
104
 
for attr_name in _gtk_attrs:
105
 
    try:
106
 
        attr = getattr(gtk, attr_name)
107
 
        if issubclass(attr, gtk.Dialog):
108
 
            class_name = 'gtk_' + attr_name
109
 
            stubbedclass = type(class_name, (_StubbedDialogMixin, attr), {})
110
 
            dialog_overrides['gtk.' + attr_name] = stubbedclass
111
 
    except TypeError:
112
 
        pass # most probably attr is not a class
113
 
 
114
 
 
115
 
#
116
 
# Glade overrides
117
 
#
118
 
 
119
 
class _ProxyMixin(object):
120
 
    """Mixin for use in proxy classes.
121
 
 
122
 
    This mixin is used in the glade stubs (see gtk_glade_XML).
123
 
 
124
 
    Note that use of this mixin breaks isinstance() for proxied widgets.
125
 
    You're better off not trying to add them to other containers by hand, etc.
126
 
    """
127
 
 
128
 
    _overrides = ()
129
 
 
130
 
    def __init__(self, obj):
131
 
        self._obj = obj
132
 
 
133
 
    def __getattr__(self, name):
134
 
        return getattr(self._obj, name)
135
 
 
136
 
 
137
 
def _createProxy(stubbedclass, overrides):
138
 
    """Create a proxy class that overrides methods listed in 'overrides'.
139
 
 
140
 
    A convenience function used in gtk_glade_XML.
141
 
    """
142
 
    cls_dict = {}
143
 
    for name in overrides:
144
 
        cls_dict[name] = getattr(stubbedclass, name).im_func
145
 
    return type(stubbedclass.__name__, (_ProxyMixin, ), cls_dict)
146
 
 
147
 
 
148
 
class gtk_glade_XML(gtk.glade.XML):
149
 
    """A stub for the gtk.glade.XML object."""
150
 
 
151
 
    __super_get_widget = gtk.glade.XML.get_widget
152
 
 
153
 
    _Dialog = gtk.Dialog
154
 
    _Window = gtk.Window
155
 
    _DialogProxy = _createProxy(dialog_overrides['gtk.Dialog'],
156
 
                                ['run', 'show', 'show_all'])
157
 
    _WindowProxy = _createProxy(gtk_Window, ['show', 'show_all'])
158
 
 
159
 
    def get_widget(self, name):
160
 
        widget = self.__super_get_widget(name)
161
 
        if isinstance(widget, self._Dialog):
162
 
            return self._DialogProxy(widget)
163
 
        elif isinstance(widget, self._Window):
164
 
            return self._WindowProxy(widget)
165
 
        else:
166
 
            return widget
167
 
 
168
 
 
169
 
#
170
 
# Unit-test and doctest helpers.
171
 
#
172
 
 
173
 
class GtkTestHelperMixin(GuiTestHelperMixin):
174
 
 
175
 
    toolkit_overrides = {'gtk.main': gtk_main,
176
 
                         'gtk.main_quit': gtk_main_quit,
177
 
                         'gtk.main_level': gtk_main_level,
178
 
                         'gtk.mainloop': gtk_main,
179
 
                         'gtk.mainquit': gtk_main_quit,
180
 
                         'gtk.main_iteration': gtk_main_iteration,
181
 
                         'gtk.main_iteration_do': gtk_main_iteration,
182
 
                         'gtk.Window': gtk_Window,
183
 
                         'gtk.glade.XML': gtk_glade_XML,
184
 
                         'pygtk.require': pygtk_require}
185
 
    toolkit_overrides.update(dialog_overrides)
186
 
 
187
 
 
188
 
# unittest helper
189
 
class GtkTestCase(GtkTestHelperMixin, unittest.TestCase):
190
 
    """A convenience TestCase for use in GTK application unit tests."""
191
 
 
192
 
# doctest helpers
193
 
doctesthelper = DoctestHelper(GtkTestHelperMixin)
194
 
 
195
 
setUp_param = doctesthelper.setUp_param
196
 
setUp = doctesthelper.setUp
197
 
tearDown = doctesthelper.tearDown