support.py 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136
  1. import functools
  2. import re
  3. import tkinter
  4. import unittest
  5. class AbstractTkTest:
  6. @classmethod
  7. def setUpClass(cls):
  8. cls._old_support_default_root = tkinter._support_default_root
  9. destroy_default_root()
  10. tkinter.NoDefaultRoot()
  11. cls.root = tkinter.Tk()
  12. cls.wantobjects = cls.root.wantobjects()
  13. # De-maximize main window.
  14. # Some window managers can maximize new windows.
  15. cls.root.wm_state('normal')
  16. try:
  17. cls.root.wm_attributes('-zoomed', False)
  18. except tkinter.TclError:
  19. pass
  20. @classmethod
  21. def tearDownClass(cls):
  22. cls.root.update_idletasks()
  23. cls.root.destroy()
  24. del cls.root
  25. tkinter._default_root = None
  26. tkinter._support_default_root = cls._old_support_default_root
  27. def setUp(self):
  28. self.root.deiconify()
  29. def tearDown(self):
  30. for w in self.root.winfo_children():
  31. w.destroy()
  32. self.root.withdraw()
  33. class AbstractDefaultRootTest:
  34. def setUp(self):
  35. self._old_support_default_root = tkinter._support_default_root
  36. destroy_default_root()
  37. tkinter._support_default_root = True
  38. self.wantobjects = tkinter.wantobjects
  39. def tearDown(self):
  40. destroy_default_root()
  41. tkinter._default_root = None
  42. tkinter._support_default_root = self._old_support_default_root
  43. def _test_widget(self, constructor):
  44. # no master passing
  45. x = constructor()
  46. self.assertIsNotNone(tkinter._default_root)
  47. self.assertIs(x.master, tkinter._default_root)
  48. self.assertIs(x.tk, tkinter._default_root.tk)
  49. x.destroy()
  50. destroy_default_root()
  51. tkinter.NoDefaultRoot()
  52. self.assertRaises(RuntimeError, constructor)
  53. self.assertFalse(hasattr(tkinter, '_default_root'))
  54. def destroy_default_root():
  55. if getattr(tkinter, '_default_root', None):
  56. tkinter._default_root.update_idletasks()
  57. tkinter._default_root.destroy()
  58. tkinter._default_root = None
  59. def simulate_mouse_click(widget, x, y):
  60. """Generate proper events to click at the x, y position (tries to act
  61. like an X server)."""
  62. widget.event_generate('<Enter>', x=0, y=0)
  63. widget.event_generate('<Motion>', x=x, y=y)
  64. widget.event_generate('<ButtonPress-1>', x=x, y=y)
  65. widget.event_generate('<ButtonRelease-1>', x=x, y=y)
  66. import _tkinter
  67. tcl_version = tuple(map(int, _tkinter.TCL_VERSION.split('.')))
  68. def requires_tcl(*version):
  69. if len(version) <= 2:
  70. return unittest.skipUnless(tcl_version >= version,
  71. 'requires Tcl version >= ' + '.'.join(map(str, version)))
  72. def deco(test):
  73. @functools.wraps(test)
  74. def newtest(self):
  75. if get_tk_patchlevel() < version:
  76. self.skipTest('requires Tcl version >= ' +
  77. '.'.join(map(str, version)))
  78. test(self)
  79. return newtest
  80. return deco
  81. _tk_patchlevel = None
  82. def get_tk_patchlevel():
  83. global _tk_patchlevel
  84. if _tk_patchlevel is None:
  85. tcl = tkinter.Tcl()
  86. _tk_patchlevel = tcl.info_patchlevel()
  87. return _tk_patchlevel
  88. units = {
  89. 'c': 72 / 2.54, # centimeters
  90. 'i': 72, # inches
  91. 'm': 72 / 25.4, # millimeters
  92. 'p': 1, # points
  93. }
  94. def pixels_conv(value):
  95. return float(value[:-1]) * units[value[-1:]]
  96. def tcl_obj_eq(actual, expected):
  97. if actual == expected:
  98. return True
  99. if isinstance(actual, _tkinter.Tcl_Obj):
  100. if isinstance(expected, str):
  101. return str(actual) == expected
  102. if isinstance(actual, tuple):
  103. if isinstance(expected, tuple):
  104. return (len(actual) == len(expected) and
  105. all(tcl_obj_eq(act, exp)
  106. for act, exp in zip(actual, expected)))
  107. return False
  108. def widget_eq(actual, expected):
  109. if actual == expected:
  110. return True
  111. if isinstance(actual, (str, tkinter.Widget)):
  112. if isinstance(expected, (str, tkinter.Widget)):
  113. return str(actual) == str(expected)
  114. return False