Commit | Line | Data |
---|---|---|
86530b38 AT |
1 | #!/bin/env python |
2 | ||
3 | # This is a rough collection of tests that can not be automated. | |
4 | # To add a new test, create a function with name ending in '_test'. | |
5 | ||
6 | import os | |
7 | import string | |
8 | import time | |
9 | import sys | |
10 | import Test | |
11 | import Tkinter | |
12 | import Pmw | |
13 | ||
14 | # ---------------------------------------------------------------------- | |
15 | ||
16 | def scrolledframeflashing_test(): | |
17 | # Script which demonstrates continuous flashing of dynamic scrollbars | |
18 | # in Pmw.ScrolledFrame. | |
19 | # | |
20 | # When this script is run, the two scrollbars will be continuously | |
21 | # mapped and unmapped and the window will continuously change size. | |
22 | ||
23 | frame = Tkinter.Frame(root) | |
24 | frame.pack(fill = 'both', expand = 1) | |
25 | ||
26 | sf = Pmw.ScrolledFrame(frame, borderframe = 0) | |
27 | sf.pack(fill = 'both', expand = 1) | |
28 | ||
29 | inner = Tkinter.Frame(sf.interior(), | |
30 | width = 401, | |
31 | height = 300, | |
32 | borderwidth = 0, | |
33 | highlightthickness = 0, | |
34 | ) | |
35 | inner.pack(fill = 'both', expand = 1) | |
36 | ||
37 | # ---------------------------------------------------------------------- | |
38 | ||
39 | def scrolledlistboxflashing_test(): | |
40 | # Script which demonstrates continuous flashing of dynamic scrollbars | |
41 | # in Pmw.ScrolledListBox. | |
42 | # | |
43 | # When this script is run, the two scrollbars will be continuously | |
44 | # mapped and unmapped and the window will continuously change size. | |
45 | ||
46 | frame = Tkinter.Frame(root) | |
47 | frame.pack(fill = 'both', expand = 1) | |
48 | ||
49 | sf = Pmw.ScrolledListBox(frame, | |
50 | listbox_width = 20, | |
51 | listbox_height = 10 | |
52 | ) | |
53 | sf.pack(fill = 'both', expand = 1) | |
54 | for i in range(11): | |
55 | sf.insert('end', '2' * 20) | |
56 | ||
57 | # ---------------------------------------------------------------------- | |
58 | ||
59 | def scrolledlistboxflashing2_test(): | |
60 | # Another script which demonstrates continuous flashing of dynamic | |
61 | # scrollbars in Pmw.ScrolledListBox under Pmw.0.8. | |
62 | # | |
63 | # When this script is run, the two scrollbars will be continuously | |
64 | # mapped and unmapped and the window will continuously change size. | |
65 | # | |
66 | # (This did not display error when tried with Pmw.0.8, 99/8/3) | |
67 | ||
68 | def insert(): | |
69 | sectionList = ['1', '2', '3', '4', '5', '6', '7', '8', '9', | |
70 | '123456789012345678901'] | |
71 | for counter in sectionList: | |
72 | slb.insert('end', counter) | |
73 | ||
74 | def clear(): | |
75 | slb.delete(0, 'end') | |
76 | ||
77 | global slb | |
78 | slb = Pmw.ScrolledListBox(root) | |
79 | slb.pack() | |
80 | ||
81 | root.after(2000,insert) | |
82 | root.after(3000,clear) | |
83 | root.after(4000,insert) | |
84 | ||
85 | root.geometry('400x400') | |
86 | ||
87 | # ---------------------------------------------------------------------- | |
88 | ||
89 | def scrolledtextflashing_test(): | |
90 | # Script which demonstrates continuous flashing of dynamic scrollbars | |
91 | # in Pmw.ScrolledText. | |
92 | # | |
93 | # When this script is run, the two scrollbars will be continuously | |
94 | # mapped and unmapped and the window will continuously change size. | |
95 | ||
96 | frame = Tkinter.Frame(root) | |
97 | frame.pack(fill = 'both', expand = 1) | |
98 | ||
99 | sf = Pmw.ScrolledText(frame, | |
100 | text_width = 20, | |
101 | text_height = 10, | |
102 | text_wrap = 'none', | |
103 | borderframe = 0 | |
104 | ) | |
105 | sf.pack(fill = 'both', expand = 1) | |
106 | for i in range(11): | |
107 | sf.insert('end', '2' * 20) | |
108 | if i != 10: | |
109 | sf.insert('end', '\n') | |
110 | ||
111 | # ---------------------------------------------------------------------- | |
112 | ||
113 | def scrolledcanvasflashing_test(): | |
114 | # Script which demonstrates continuous flashing of dynamic scrollbars | |
115 | # in Pmw.ScrolledCanvas. | |
116 | # | |
117 | # When this script is run, the two scrollbars will be continuously | |
118 | # mapped and unmapped and the window will continuously change size. | |
119 | ||
120 | frame = Tkinter.Frame(root) | |
121 | frame.pack(fill = 'both', expand = 1) | |
122 | ||
123 | sf = Pmw.ScrolledCanvas(frame, | |
124 | canvas_scrollregion = (0, 0, 301, 200), | |
125 | canvas_width=300, | |
126 | canvas_height=200, | |
127 | borderframe = 0 | |
128 | ) | |
129 | sf.pack(fill = 'both', expand = 1) | |
130 | ||
131 | # ---------------------------------------------------------------------- | |
132 | ||
133 | def scrolledframeflashing2_test(): | |
134 | # The two scrollbars will be continuously mapped and unmapped, but | |
135 | # the toplevel window will remain the same size. | |
136 | ||
137 | root.geometry('550x500') | |
138 | ||
139 | frame = Tkinter.Frame() | |
140 | frame.pack() | |
141 | ||
142 | sf = Pmw.ScrolledFrame(frame, borderframe = 0) | |
143 | sf.pack(fill = 'both') | |
144 | ||
145 | inner = Tkinter.Frame(sf.interior(), | |
146 | width = 401, | |
147 | height = 300, | |
148 | borderwidth = 0, | |
149 | highlightthickness = 0, | |
150 | ) | |
151 | inner.pack() | |
152 | ||
153 | # ---------------------------------------------------------------------- | |
154 | ||
155 | def reinitialise_test(): | |
156 | global text | |
157 | text = """ | |
158 | Demonstrates bug in Pmw.0.8.1 and earlier. | |
159 | Click on this button, click on OK in the dialog, then Exit below. | |
160 | When this window appears again, clicking on this button gives | |
161 | an error: | |
162 | TclError: can't invoke "wm" command: application has been destroyed | |
163 | """ | |
164 | class test: | |
165 | def __init__(self): | |
166 | root = Tkinter.Tk() | |
167 | Pmw.initialise(root) | |
168 | self.messagedialog = Pmw.MessageDialog(message_text = 'Testing') | |
169 | self.messagedialog.withdraw() | |
170 | button = Tkinter.Button( | |
171 | text = text, command = self.messagedialog.activate) | |
172 | button.pack(pady = 20) | |
173 | exit = Tkinter.Button(text = 'Exit', command = root.destroy) | |
174 | exit.pack(pady = 20) | |
175 | root.mainloop() | |
176 | ||
177 | test() | |
178 | test() | |
179 | ||
180 | # ---------------------------------------------------------------------- | |
181 | ||
182 | def componentgroup_test(): | |
183 | def addbutton(bb): | |
184 | bb.configure(Button_background = 'yellow') | |
185 | bb.add('Apples') | |
186 | bb.after(3000, lambda bb = bb: | |
187 | bb.configure(Button_background = 'green')) | |
188 | ||
189 | bb = Pmw.ButtonBox(Button_background = 'red') | |
190 | bb.add('Bananas') | |
191 | bb.pack() | |
192 | ||
193 | mb = Pmw.MenuBar(Button_background = 'red') | |
194 | mb.configure(Button_background = 'yellow') | |
195 | mb.pack() | |
196 | ||
197 | pw = Pmw.PanedWidget(Frame_background = 'red') | |
198 | pw.configure(Frame_background = 'yellow') | |
199 | pw.pack() | |
200 | ||
201 | rs = Pmw.RadioSelect(Button_background = 'red') | |
202 | rs.configure(Button_background = 'yellow') | |
203 | rs.pack() | |
204 | ||
205 | bb.after(3000, lambda bb = bb, addbutton = addbutton: addbutton(bb)) | |
206 | ||
207 | # ---------------------------------------------------------------------- | |
208 | ||
209 | def balloon_test(): | |
210 | ||
211 | # TODO | |
212 | ||
213 | # Test that the balloon does not reappear if the mouse button is | |
214 | # pressed down inside a widget and then, while the mouse button is | |
215 | # being held down, the mouse is moved outside of the widget and | |
216 | # then moved back over the widget. | |
217 | ||
218 | # Test that when a widget is destroyed while a balloon is being | |
219 | # displayed for it then the balloon is withdrawn. | |
220 | ||
221 | # Test that when a widget is destroyed while a balloon is being | |
222 | # displayed for another widget then the balloon is not withdrawn. | |
223 | ||
224 | # Test that there is no eror when a widget is destroyed during the | |
225 | # initwait period (between when the mouse enters the widget and | |
226 | # when the initwait timer goes off). | |
227 | ||
228 | # Test that if unbind() is called on a widget that triggered the | |
229 | # balloon to be displayed then the balloon is withdrawn. Also | |
230 | # test that if another widget triggered the balloon then the | |
231 | # balloon is not withdrawn. | |
232 | ||
233 | # Test that if tagunbind() is called on a canvas or text item that | |
234 | # triggered the balloon to be displayed then the balloon is | |
235 | # withdrawn. Also test that if another widget or item triggered | |
236 | # the balloon then the balloon is not withdrawn. | |
237 | ||
238 | pass | |
239 | ||
240 | # ---------------------------------------------------------------------- | |
241 | ||
242 | # A class which prints out a message when an instance is deleted. | |
243 | class MyToplevel(Tkinter.Toplevel): | |
244 | ||
245 | def __init__(self): | |
246 | Tkinter.Toplevel.__init__(self) | |
247 | ||
248 | def __del__(self): | |
249 | print 'Window deleted' | |
250 | ||
251 | def _runMemoryLeakTest(): | |
252 | global top | |
253 | top = MyToplevel() | |
254 | Pmw.MegaToplevel(top) | |
255 | Pmw.AboutDialog(top) | |
256 | Pmw.ComboBoxDialog(top) | |
257 | Pmw.CounterDialog(top) | |
258 | Pmw.Dialog(top) | |
259 | Pmw.MessageDialog(top) | |
260 | Pmw.PromptDialog(top) | |
261 | Pmw.SelectionDialog(top) | |
262 | Pmw.TextDialog(top) | |
263 | ||
264 | Pmw.ButtonBox(top).pack() | |
265 | Pmw.ComboBox(top).pack() | |
266 | Pmw.Counter(top).pack() | |
267 | Pmw.EntryField(top).pack() | |
268 | Pmw.Group(top).pack() | |
269 | Pmw.LabeledWidget(top).pack() | |
270 | Pmw.MenuBar(top).pack() | |
271 | Pmw.MessageBar(top).pack() | |
272 | Pmw.NoteBook(top).pack() | |
273 | Pmw.OptionMenu(top).pack() | |
274 | Pmw.PanedWidget(top).pack() | |
275 | Pmw.RadioSelect(top).pack() | |
276 | Pmw.ScrolledCanvas(top).pack() | |
277 | Pmw.ScrolledField(top).pack() | |
278 | Pmw.ScrolledFrame(top).pack() | |
279 | Pmw.ScrolledListBox(top).pack() | |
280 | Pmw.ScrolledText(top).pack() | |
281 | Pmw.TimeCounter(top).pack() | |
282 | ||
283 | def _killMemoryLeakTest(): | |
284 | global top | |
285 | top.destroy() | |
286 | del top | |
287 | ||
288 | memoryLeakMessage = """ | |
289 | Click on the "Run test" button to create instances of | |
290 | all Pmw megawidgets. Then click on the "Destroy" button. | |
291 | The message "Window deleted" should be printed to | |
292 | standard output. | |
293 | """ | |
294 | def memoryleak_test(): | |
295 | label = Tkinter.Label(text = memoryLeakMessage) | |
296 | label.pack() | |
297 | run = Tkinter.Button(text = 'Run test', command = _runMemoryLeakTest) | |
298 | run.pack() | |
299 | kill = Tkinter.Button(text = 'Destroy', command = _killMemoryLeakTest) | |
300 | kill.pack() | |
301 | ||
302 | # ---------------------------------------------------------------------- | |
303 | ||
304 | def memoryleak2_test(): | |
305 | ||
306 | print 'This test continuously creates and deletes megawidgets and' | |
307 | print 'their components. It calls the "top" program, so' | |
308 | print 'may not work on non-Unix operating systems. Run it for a long,' | |
309 | print 'long time and check that the process memory size does not' | |
310 | print 'continue to increase. Kill with <Control-C>.' | |
311 | ||
312 | pid = os.getpid() | |
313 | ||
314 | label = Tkinter.Label() | |
315 | label.pack() | |
316 | ||
317 | # Setup each test: | |
318 | ||
319 | # 1. Create/delete all megawidgets: | |
320 | megawidgets = ( | |
321 | Pmw.AboutDialog, Pmw.Balloon, Pmw.ButtonBox, Pmw.ComboBox, | |
322 | Pmw.ComboBoxDialog, Pmw.Counter, Pmw.CounterDialog, Pmw.Dialog, | |
323 | Pmw.EntryField, Pmw.Group, Pmw.HistoryText, Pmw.LabeledWidget, | |
324 | Pmw.MainMenuBar, Pmw.MenuBar, Pmw.MessageBar, Pmw.MessageDialog, | |
325 | Pmw.NoteBook, Pmw.OptionMenu, Pmw.PanedWidget, Pmw.PromptDialog, | |
326 | Pmw.RadioSelect, Pmw.ScrolledCanvas, Pmw.ScrolledField, | |
327 | Pmw.ScrolledFrame, Pmw.ScrolledListBox, Pmw.ScrolledText, | |
328 | Pmw.SelectionDialog, Pmw.TextDialog, Pmw.TimeCounter, | |
329 | ) | |
330 | ||
331 | # 2. Balloon binding: | |
332 | toplevel = Tkinter.Toplevel() | |
333 | balloon = Pmw.Balloon(toplevel) | |
334 | button = Tkinter.Button(toplevel) | |
335 | button.pack() | |
336 | canvas = Tkinter.Canvas(toplevel) | |
337 | item = canvas.create_rectangle(0, 0, 100, 100) | |
338 | canvas.pack() | |
339 | ||
340 | # 3. Adding and deleting menu: | |
341 | toplevel = Tkinter.Toplevel() | |
342 | mainmenu = Pmw.MainMenuBar(toplevel) | |
343 | mainmenu.addmenu('Foo', 'help') | |
344 | toplevel.configure(menu = mainmenu) | |
345 | ||
346 | # 4. Adding and deleting notebook page: | |
347 | toplevel = Tkinter.Toplevel() | |
348 | notebook = Pmw.NoteBook(toplevel) | |
349 | notebook.pack() | |
350 | ||
351 | # 5. Adding and deleting panedwidget pane: | |
352 | toplevel = Tkinter.Toplevel() | |
353 | panedwidget = Pmw.PanedWidget(toplevel) | |
354 | panedwidget.pack() | |
355 | panedwidget.insert('Foo', size = 100) | |
356 | ||
357 | # 6. Adding and deleting MenuBar menu: | |
358 | toplevel = Tkinter.Toplevel() | |
359 | menubar = Pmw.MenuBar(toplevel) | |
360 | menubar.pack() | |
361 | ||
362 | # 7. Setting OptionMenu items: | |
363 | toplevel = Tkinter.Toplevel() | |
364 | optionmenu = Pmw.OptionMenu(toplevel, items = ('XXX', 'YYY', 'ZZZ')) | |
365 | optionmenu.pack() | |
366 | ||
367 | # 8. Setting Tkinter.Canvas scrollcommand option: | |
368 | toplevel = Tkinter.Toplevel() | |
369 | scrollcanvas = Pmw.ScrolledCanvas(toplevel) | |
370 | scrollcanvas.pack() | |
371 | ||
372 | global prevSize | |
373 | prevSize = -1 | |
374 | ||
375 | # Loop and run each test: | |
376 | count = 0 | |
377 | while 1: | |
378 | count = count + 1 | |
379 | label.configure(text = count) | |
380 | ||
381 | # 1. Create/delete all megawidgets: | |
382 | for widgetClass in megawidgets: | |
383 | widget = widgetClass() | |
384 | if widgetClass == Pmw.MainMenuBar: | |
385 | root.configure(menu = widget) | |
386 | elif hasattr(widgetClass, 'pack'): | |
387 | widget.pack() | |
388 | root.update() | |
389 | widget.destroy() | |
390 | ||
391 | # 2. Balloon binding: | |
392 | balloon.bind(button, 'help') | |
393 | balloon.tagbind(canvas, item, 'help') | |
394 | # tagbind leaks due to a bug in Tkinter (v1.127) Canvas - it adds | |
395 | # bindings to self._tagcommands but does not delete them. | |
396 | root.update() | |
397 | ||
398 | # 3. Adding and deleting MainMenuBar menu: | |
399 | mainmenu.addmenu('File', 'help') | |
400 | root.update() | |
401 | mainmenu.deletemenu('File') | |
402 | root.update() | |
403 | ||
404 | # 4. Adding and deleting notebook page: | |
405 | notebook.insert('File') | |
406 | root.update() | |
407 | notebook.delete('File') | |
408 | root.update() | |
409 | ||
410 | # 5. Adding and deleting panedwidget pane: | |
411 | panedwidget.insert('File', size = 100) | |
412 | root.update() | |
413 | panedwidget.delete('File') | |
414 | root.update() | |
415 | ||
416 | # 6. Adding and deleting MenuBar menu: | |
417 | menubar.addmenu('File', 'help') | |
418 | root.update() | |
419 | menubar.deletemenu('File') | |
420 | root.update() | |
421 | ||
422 | # 7. Setting OptionMenu items: | |
423 | optionmenu.setitems(('aaa', 'bbb', 'ccc')) | |
424 | root.update() | |
425 | ||
426 | # 8. Setting Tkinter.Canvas scrollcommand option: | |
427 | scrollcanvas.configure(hscrollmode = 'static') | |
428 | scrollcanvas.configure(hscrollmode = 'dynamic') | |
429 | ||
430 | # Check memory usage: | |
431 | # lines = os.popen('top').readlines() | |
432 | lines = os.popen('top -b -n 1 -p %d' % pid).readlines() | |
433 | for line in lines: | |
434 | # if string.find(line, 'python1.5.2') > 0: | |
435 | if string.find(line, '^ *%d' % pid) > 0: | |
436 | break | |
437 | # size = string.atoi(string.lstrip(line[27:32])) | |
438 | size = string.atoi(string.lstrip(line[22:29])) | |
439 | if prevSize != size: | |
440 | print time.strftime('%H:%M:%S', time.localtime(time.time())), | |
441 | print line[:-1] | |
442 | prevSize = size | |
443 | ||
444 | # ---------------------------------------------------------------------- | |
445 | ||
446 | def usageExit(): | |
447 | print 'Usage:', sys.argv[0], '<test>' | |
448 | print ' where <test> is one of:' | |
449 | for test in tests: | |
450 | print ' ', test | |
451 | sys.exit() | |
452 | ||
453 | tests = [] | |
454 | for name in locals().keys(): | |
455 | if name[-5:] == '_test': | |
456 | tests.append(name) | |
457 | tests.sort() | |
458 | ||
459 | if len(sys.argv) != 2: | |
460 | usageExit() | |
461 | ||
462 | testName = sys.argv[1] | |
463 | if testName not in tests: | |
464 | print 'Unknown test "' + testName + '"' | |
465 | usageExit() | |
466 | ||
467 | if testName == 'reinitialise_test': | |
468 | # Run this by itself, since it calls Tkinter.Tk, mainloop, etc. | |
469 | reinitialise_test() | |
470 | sys.exit() | |
471 | ||
472 | # Use Pmw version in this distribution: | |
473 | Test.initialise() | |
474 | root = Test.root | |
475 | root.deiconify() | |
476 | ||
477 | # To use a different version of Pmw, comment out the three above lines | |
478 | # and the "import Test" line and uncomment these three: | |
479 | # root = Tkinter.Tk() | |
480 | # Pmw.setversion('1.0') | |
481 | # Pmw.initialise(root) | |
482 | ||
483 | testFunction = locals()[testName] | |
484 | testFunction() | |
485 | ||
486 | if testName != 'memoryleak2_test': | |
487 | # This does not use mainloop. | |
488 | root.mainloop() |