1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405
|
from threading import Event
from time import sleep
from unittest.mock import MagicMock
from guizero import Text, Picture
from tkinter import Spinbox
SET_FONT = "Times New Roman"
TEST_FONTS = ["Times New Roman", "Liberation Serif"]
def schedule_after_test(app, widget):
callback_event = Event()
def callback():
callback_event.set()
assert not callback_event.is_set()
widget.after(0, callback)
# call tk to update the app
app.tk.update()
assert callback_event.is_set()
#widget.cancel(callback)
def schedule_repeat_test(app, widget):
callback_event = Event()
def callback():
callback_event.set()
widget.cancel(callback)
assert not callback_event.is_set()
widget.repeat(0, callback)
# call tk to update the app
app.tk.update()
assert callback_event.is_set()
def destroy_test(widget):
assert widget.tk.winfo_exists()
widget.destroy()
assert not widget.tk.winfo_exists()
def enable_test(widget):
assert widget.enabled
widget.enabled = False
assert not widget.enabled
widget.enabled = True
assert widget.enabled
widget.disable()
assert not widget.enabled
widget.enable()
assert widget.enabled
# doesn't work under pytest, app always returns None from focus_get() run
# direct from Python it works fine.
def focus_test(app, widget):
app.focus()
app.tk.update()
assert app.tk.focus_get() == app.tk
widget.focus()
app.tk.update()
assert app.tk.focus_get() == widget.tk
def display_test(widget):
assert widget.visible
widget.visible = False
assert not widget.visible
widget.visible = True
assert widget.visible
widget.hide()
assert not widget.visible
widget.show()
assert widget.visible
def color_test(widget):
default = widget.bg
widget.bg = "red"
assert widget.bg == "red"
widget.bg = "#ff0000"
assert widget.bg == "#ff0000"
widget.bg = (255, 0, 0)
assert widget.bg == "#ff0000"
widget.bg = None
assert widget.bg == default
def size_pixel_test(widget):
default = widget.width
widget.width = 666
assert widget.width == 666
widget.width = None
assert widget.width == default
default = widget.height
widget.height = 666
assert widget.height == 666
widget.height = None
assert widget.height == default
def size_text_test(widget):
default = widget.width
widget.width = 30
assert widget.width == 30
widget.width = None
assert widget.width == default
default = widget.height
widget.height = 10
assert widget.height == 10
widget.height = None
assert widget.height == default
def size_fill_test(widget):
default = widget.width
widget.width = "fill"
assert widget.width == "fill"
widget.width = None
assert widget.width == default
default = widget.height
widget.height = "fill"
assert widget.height == "fill"
widget.height = None
assert widget.height == default
def text_test(widget):
default = widget.font
widget.font = SET_FONT
assert widget.font in TEST_FONTS
widget.font = None
assert widget.font == default
default = widget.text_color
widget.text_color = "red"
assert widget.text_color == "red"
widget.text_color = "#ff0000"
assert widget.text_color == "#ff0000"
widget.text_color = (255, 0, 0)
assert widget.text_color == "#ff0000"
widget.text_color = None
assert widget.text_color == default
default = widget.text_size
widget.text_size = 16
assert widget.text_size == 16
widget.text_size = None
assert widget.text_size == default
def events_test(widget):
events_to_test = (
("when_clicked", "<when_clicked>"),
("when_left_button_pressed", "<when_left_button_pressed>"),
("when_left_button_released", "<when_left_button_released>"),
("when_right_button_pressed", "<when_right_button_pressed>"),
("when_right_button_released", "<when_right_button_released>"),
("when_key_pressed", "<when_key_pressed>"),
("when_key_released", "<when_key_released>"),
("when_mouse_enters", "<when_mouse_enters>"),
("when_mouse_leaves", "<when_mouse_leaves>"),
("when_mouse_dragged", "<when_mouse_dragged>"),
)
callback_event = Event()
def callback():
callback_event.set()
callback_with_param_event = Event()
def callback_with_param(e):
assert e.widget == widget
assert e.key == "A"
assert e.x == 1
assert e.y == 2
assert e.display_x == 3
assert e.display_y == 4
callback_with_param_event.set()
for event_to_test in events_to_test:
# set the when_attribute to the callback
setattr(widget, event_to_test[0], callback)
assert not callback_event.is_set()
# mock the event
mock_event(widget, event_to_test[1], "A", 1, 2, 3, 4)
assert callback_event.is_set()
callback_with_param_event.clear()
# set the when_attribute to the callback with a parameter
setattr(widget, event_to_test[0], callback_with_param)
assert not callback_with_param_event.is_set()
# mock the event
mock_event(widget, event_to_test[1], "A", 1, 2, 3, 4)
assert callback_with_param_event.is_set()
callback_event.clear()
callback_with_param_event.clear()
# set the when_attribute to None
setattr(widget, event_to_test[0], None)
mock_event(widget, event_to_test[1], "A", 1, 2, 3, 4)
# make sure its not called
assert not callback_event.is_set()
assert not callback_with_param_event.is_set()
def mock_event(widget, ref, key, x, y, display_x, display_y):
# you cant invoke a tk event so we will mock it
# create a mock event
# get the event callback
event_callback = widget.events._refs[ref]
# mock a tk event
tk_event = MagicMock()
tk_event.char = key
tk_event.x = x
tk_event.y = y
tk_event.x_root = display_x
tk_event.y_root = display_y
# call the event callback
event_callback._event_callback(tk_event)
def cascaded_properties_test(container, widget, text):
container.bg = "red"
container.enabled = False
assert widget.bg == "red"
assert not widget.enabled
if text:
container.text_color = "purple"
assert widget.text_color == "purple"
container.text_size = 16
assert widget.text_size == 16
def inherited_properties_test(container, widget_create, text):
container.bg = "red"
container.enabled = False
if text:
container.text_color = "purple"
container.text_size = 16
w = widget_create()
assert w.bg == "red"
assert not container.enabled
if text:
assert w.text_color == "purple"
assert w.text_size == 16
def cascading_enable_test(container):
def check_children(container, test_value):
for child in container.children:
assert child.enabled == test_value
assert container.enabled
check_children(container, True)
container.enabled = False
assert not container.enabled
check_children(container, False)
container.enabled = True
assert container.enabled
check_children(container, True)
container.disable()
assert not container.enabled
check_children(container, False)
container.enable()
assert container.enabled
check_children(container, True)
def cascading_properties_test(container):
t = Text(container, color=None, size=None, font=None)
p = Picture(container)
container.bg = "red"
container.text_color = "purple"
container.text_size = 16
container.font = SET_FONT
container.enabled = False
assert t.bg == "red"
assert t.text_color == "purple"
assert t.text_size == 16
assert t.font in TEST_FONTS
assert t.enabled == False
assert p.bg == "red"
assert p.enabled == False
# test that destroying widgets removes them as children
p.destroy()
container.bg = "green"
assert t.bg == "green"
def inheriting_properties_test(container):
container.bg = "red"
container.text_color = "purple"
container.text_size = 16
container.font = SET_FONT
container.enabled = False
t = Text(container, color=None, size=None, font=None)
assert t.bg == "red"
assert t.text_color == "purple"
assert t.text_size == 16
assert t.font in TEST_FONTS
assert not t.enabled
p = Picture(container)
assert p.bg == "red"
assert not p.enabled
def full_screen_test(window):
assert window.full_screen == False
window.full_screen = True
assert window.full_screen == True
window.full_screen = False
assert window.full_screen == False
window.set_full_screen()
assert window.full_screen == True
window.exit_full_screen()
assert window.full_screen == False
def add_tk_widget_test(container):
s = Spinbox(from_=0, to=10)
sw = container.add_tk_widget(s)
assert s is not None
assert sw is not None
assert sw.grid is None
assert sw.align is None
assert sw.enabled
assert sw.visible
assert sw.width is None
assert sw.height is None
s2 = Spinbox(from_=0, to=10)
sw = container.add_tk_widget(s2, align="left", visible=False, enabled=False, width="fill", height="fill")
assert s is not None
assert sw is not None
assert sw.align == "left"
assert not sw.enabled
assert not sw.visible
assert sw.width == "fill"
assert sw.height == "fill"
def auto_layout_test(widget, align):
assert widget.master.layout == "auto"
side = "top" if align is None else align
assert widget.tk.pack_info()["side"] == side
widget.align = "left"
assert widget.tk.pack_info()["side"] == "left"
widget.align = "right"
assert widget.tk.pack_info()["side"] == "right"
widget.align = "top"
assert widget.tk.pack_info()["side"] == "top"
widget.align = "bottom"
assert widget.tk.pack_info()["side"] == "bottom"
def grid_layout_test(widget, x, y, col_span, row_span, align):
sticky = {"top": "n", "bottom": "s", "left": "w", "right": "e", None: ""}
# test initial values
assert widget.master.layout == "grid"
assert int(widget.tk.grid_info()["column"]) == x
assert int(widget.tk.grid_info()["row"]) == y
assert int(widget.tk.grid_info()["columnspan"]) == col_span
assert int(widget.tk.grid_info()["rowspan"]) == row_span
assert widget.tk.grid_info()["sticky"] == sticky[align]
# change grid values
widget.grid[0] = 3
widget.grid[1] = 4
assert int(widget.tk.grid_info()["column"]) == 3
assert int(widget.tk.grid_info()["row"]) == 4
assert int(widget.tk.grid_info()["columnspan"]) == col_span
assert int(widget.tk.grid_info()["rowspan"]) == row_span
assert widget.tk.grid_info()["sticky"] == sticky[align]
widget.grid = [5,6]
assert int(widget.tk.grid_info()["column"]) == 5
assert int(widget.tk.grid_info()["row"]) == 6
assert int(widget.tk.grid_info()["columnspan"]) == 1
assert int(widget.tk.grid_info()["rowspan"]) == 1
assert widget.tk.grid_info()["sticky"] == sticky[align]
widget.grid = (7,8)
assert int(widget.tk.grid_info()["column"]) == 7
assert int(widget.tk.grid_info()["row"]) == 8
assert int(widget.tk.grid_info()["columnspan"]) == 1
assert int(widget.tk.grid_info()["rowspan"]) == 1
assert widget.tk.grid_info()["sticky"] == sticky[align]
# change span
widget.grid = [9, 10, 11, 12]
assert int(widget.tk.grid_info()["column"]) == 9
assert int(widget.tk.grid_info()["row"]) == 10
assert int(widget.tk.grid_info()["columnspan"]) == 11
assert int(widget.tk.grid_info()["rowspan"]) == 12
assert widget.tk.grid_info()["sticky"] == sticky[align]
# change align
widget.align = "left"
assert widget.tk.grid_info()["sticky"] == sticky["left"]
|