1import unittest 2import tkinter 3from tkinter import TclError 4import os 5from test.support import requires 6 7from tkinter.test.support import (requires_tcl, 8 get_tk_patchlevel, widget_eq, 9 AbstractDefaultRootTest) 10from tkinter.test.widget_tests import ( 11 add_standard_options, 12 AbstractWidgetTest, StandardOptionsTests, IntegerSizeTests, PixelSizeTests, 13 setUpModule) 14 15requires('gui') 16 17 18def float_round(x): 19 return float(round(x)) 20 21 22class AbstractToplevelTest(AbstractWidgetTest, PixelSizeTests): 23 _conv_pad_pixels = False 24 25 def test_configure_class(self): 26 widget = self.create() 27 self.assertEqual(widget['class'], 28 widget.__class__.__name__.title()) 29 self.checkInvalidParam(widget, 'class', 'Foo', 30 errmsg="can't modify -class option after widget is created") 31 widget2 = self.create(class_='Foo') 32 self.assertEqual(widget2['class'], 'Foo') 33 34 def test_configure_colormap(self): 35 widget = self.create() 36 self.assertEqual(widget['colormap'], '') 37 self.checkInvalidParam(widget, 'colormap', 'new', 38 errmsg="can't modify -colormap option after widget is created") 39 widget2 = self.create(colormap='new') 40 self.assertEqual(widget2['colormap'], 'new') 41 42 def test_configure_container(self): 43 widget = self.create() 44 self.assertEqual(widget['container'], 0 if self.wantobjects else '0') 45 self.checkInvalidParam(widget, 'container', 1, 46 errmsg="can't modify -container option after widget is created") 47 widget2 = self.create(container=True) 48 self.assertEqual(widget2['container'], 1 if self.wantobjects else '1') 49 50 def test_configure_visual(self): 51 widget = self.create() 52 self.assertEqual(widget['visual'], '') 53 self.checkInvalidParam(widget, 'visual', 'default', 54 errmsg="can't modify -visual option after widget is created") 55 widget2 = self.create(visual='default') 56 self.assertEqual(widget2['visual'], 'default') 57 58 59@add_standard_options(StandardOptionsTests) 60class ToplevelTest(AbstractToplevelTest, unittest.TestCase): 61 OPTIONS = ( 62 'background', 'borderwidth', 63 'class', 'colormap', 'container', 'cursor', 'height', 64 'highlightbackground', 'highlightcolor', 'highlightthickness', 65 'menu', 'padx', 'pady', 'relief', 'screen', 66 'takefocus', 'use', 'visual', 'width', 67 ) 68 69 def create(self, **kwargs): 70 return tkinter.Toplevel(self.root, **kwargs) 71 72 def test_configure_menu(self): 73 widget = self.create() 74 menu = tkinter.Menu(self.root) 75 self.checkParam(widget, 'menu', menu, eq=widget_eq) 76 self.checkParam(widget, 'menu', '') 77 78 def test_configure_screen(self): 79 widget = self.create() 80 if widget._windowingsystem != 'x11': 81 self.skipTest('Not using Tk for X11') 82 self.assertEqual(widget['screen'], '') 83 try: 84 display = os.environ['DISPLAY'] 85 except KeyError: 86 self.skipTest('No $DISPLAY set.') 87 self.checkInvalidParam(widget, 'screen', display, 88 errmsg="can't modify -screen option after widget is created") 89 widget2 = self.create(screen=display) 90 self.assertEqual(widget2['screen'], display) 91 92 def test_configure_use(self): 93 widget = self.create() 94 self.assertEqual(widget['use'], '') 95 parent = self.create(container=True) 96 wid = hex(parent.winfo_id()) 97 with self.subTest(wid=wid): 98 widget2 = self.create(use=wid) 99 self.assertEqual(widget2['use'], wid) 100 101 102@add_standard_options(StandardOptionsTests) 103class FrameTest(AbstractToplevelTest, unittest.TestCase): 104 OPTIONS = ( 105 'background', 'borderwidth', 106 'class', 'colormap', 'container', 'cursor', 'height', 107 'highlightbackground', 'highlightcolor', 'highlightthickness', 108 'padx', 'pady', 'relief', 'takefocus', 'visual', 'width', 109 ) 110 111 def create(self, **kwargs): 112 return tkinter.Frame(self.root, **kwargs) 113 114 115@add_standard_options(StandardOptionsTests) 116class LabelFrameTest(AbstractToplevelTest, unittest.TestCase): 117 OPTIONS = ( 118 'background', 'borderwidth', 119 'class', 'colormap', 'container', 'cursor', 120 'font', 'foreground', 'height', 121 'highlightbackground', 'highlightcolor', 'highlightthickness', 122 'labelanchor', 'labelwidget', 'padx', 'pady', 'relief', 123 'takefocus', 'text', 'visual', 'width', 124 ) 125 126 def create(self, **kwargs): 127 return tkinter.LabelFrame(self.root, **kwargs) 128 129 def test_configure_labelanchor(self): 130 widget = self.create() 131 self.checkEnumParam(widget, 'labelanchor', 132 'e', 'en', 'es', 'n', 'ne', 'nw', 133 's', 'se', 'sw', 'w', 'wn', 'ws') 134 self.checkInvalidParam(widget, 'labelanchor', 'center') 135 136 def test_configure_labelwidget(self): 137 widget = self.create() 138 label = tkinter.Label(self.root, text='Mupp', name='foo') 139 self.checkParam(widget, 'labelwidget', label, expected='.foo') 140 label.destroy() 141 142 143class AbstractLabelTest(AbstractWidgetTest, IntegerSizeTests): 144 _conv_pixels = False 145 146 def test_configure_highlightthickness(self): 147 widget = self.create() 148 self.checkPixelsParam(widget, 'highlightthickness', 149 0, 1.3, 2.6, 6, -2, '10p') 150 151 152@add_standard_options(StandardOptionsTests) 153class LabelTest(AbstractLabelTest, unittest.TestCase): 154 OPTIONS = ( 155 'activebackground', 'activeforeground', 'anchor', 156 'background', 'bitmap', 'borderwidth', 'compound', 'cursor', 157 'disabledforeground', 'font', 'foreground', 'height', 158 'highlightbackground', 'highlightcolor', 'highlightthickness', 159 'image', 'justify', 'padx', 'pady', 'relief', 'state', 160 'takefocus', 'text', 'textvariable', 161 'underline', 'width', 'wraplength', 162 ) 163 164 def create(self, **kwargs): 165 return tkinter.Label(self.root, **kwargs) 166 167 168@add_standard_options(StandardOptionsTests) 169class ButtonTest(AbstractLabelTest, unittest.TestCase): 170 OPTIONS = ( 171 'activebackground', 'activeforeground', 'anchor', 172 'background', 'bitmap', 'borderwidth', 173 'command', 'compound', 'cursor', 'default', 174 'disabledforeground', 'font', 'foreground', 'height', 175 'highlightbackground', 'highlightcolor', 'highlightthickness', 176 'image', 'justify', 'overrelief', 'padx', 'pady', 'relief', 177 'repeatdelay', 'repeatinterval', 178 'state', 'takefocus', 'text', 'textvariable', 179 'underline', 'width', 'wraplength') 180 181 def create(self, **kwargs): 182 return tkinter.Button(self.root, **kwargs) 183 184 def test_configure_default(self): 185 widget = self.create() 186 self.checkEnumParam(widget, 'default', 'active', 'disabled', 'normal') 187 188 189@add_standard_options(StandardOptionsTests) 190class CheckbuttonTest(AbstractLabelTest, unittest.TestCase): 191 OPTIONS = ( 192 'activebackground', 'activeforeground', 'anchor', 193 'background', 'bitmap', 'borderwidth', 194 'command', 'compound', 'cursor', 195 'disabledforeground', 'font', 'foreground', 'height', 196 'highlightbackground', 'highlightcolor', 'highlightthickness', 197 'image', 'indicatoron', 'justify', 198 'offrelief', 'offvalue', 'onvalue', 'overrelief', 199 'padx', 'pady', 'relief', 'selectcolor', 'selectimage', 'state', 200 'takefocus', 'text', 'textvariable', 201 'tristateimage', 'tristatevalue', 202 'underline', 'variable', 'width', 'wraplength', 203 ) 204 205 def create(self, **kwargs): 206 return tkinter.Checkbutton(self.root, **kwargs) 207 208 209 def test_configure_offvalue(self): 210 widget = self.create() 211 self.checkParams(widget, 'offvalue', 1, 2.3, '', 'any string') 212 213 def test_configure_onvalue(self): 214 widget = self.create() 215 self.checkParams(widget, 'onvalue', 1, 2.3, '', 'any string') 216 217 def test_unique_variables(self): 218 frames = [] 219 buttons = [] 220 for i in range(2): 221 f = tkinter.Frame(self.root) 222 f.pack() 223 frames.append(f) 224 for j in 'AB': 225 b = tkinter.Checkbutton(f, text=j) 226 b.pack() 227 buttons.append(b) 228 variables = [str(b['variable']) for b in buttons] 229 self.assertEqual(len(set(variables)), 4, variables) 230 231 def test_same_name(self): 232 f1 = tkinter.Frame(self.root) 233 f2 = tkinter.Frame(self.root) 234 b1 = tkinter.Checkbutton(f1, name='test', text='Test1') 235 b2 = tkinter.Checkbutton(f2, name='test', text='Test2') 236 237 v = tkinter.IntVar(self.root, name='test') 238 b1.select() 239 self.assertEqual(v.get(), 1) 240 b2.deselect() 241 self.assertEqual(v.get(), 0) 242 243 244@add_standard_options(StandardOptionsTests) 245class RadiobuttonTest(AbstractLabelTest, unittest.TestCase): 246 OPTIONS = ( 247 'activebackground', 'activeforeground', 'anchor', 248 'background', 'bitmap', 'borderwidth', 249 'command', 'compound', 'cursor', 250 'disabledforeground', 'font', 'foreground', 'height', 251 'highlightbackground', 'highlightcolor', 'highlightthickness', 252 'image', 'indicatoron', 'justify', 'offrelief', 'overrelief', 253 'padx', 'pady', 'relief', 'selectcolor', 'selectimage', 'state', 254 'takefocus', 'text', 'textvariable', 255 'tristateimage', 'tristatevalue', 256 'underline', 'value', 'variable', 'width', 'wraplength', 257 ) 258 259 def create(self, **kwargs): 260 return tkinter.Radiobutton(self.root, **kwargs) 261 262 def test_configure_value(self): 263 widget = self.create() 264 self.checkParams(widget, 'value', 1, 2.3, '', 'any string') 265 266 267@add_standard_options(StandardOptionsTests) 268class MenubuttonTest(AbstractLabelTest, unittest.TestCase): 269 OPTIONS = ( 270 'activebackground', 'activeforeground', 'anchor', 271 'background', 'bitmap', 'borderwidth', 272 'compound', 'cursor', 'direction', 273 'disabledforeground', 'font', 'foreground', 'height', 274 'highlightbackground', 'highlightcolor', 'highlightthickness', 275 'image', 'indicatoron', 'justify', 'menu', 276 'padx', 'pady', 'relief', 'state', 277 'takefocus', 'text', 'textvariable', 278 'underline', 'width', 'wraplength', 279 ) 280 _conv_pixels = round 281 282 def create(self, **kwargs): 283 return tkinter.Menubutton(self.root, **kwargs) 284 285 def test_configure_direction(self): 286 widget = self.create() 287 self.checkEnumParam(widget, 'direction', 288 'above', 'below', 'flush', 'left', 'right') 289 290 def test_configure_height(self): 291 widget = self.create() 292 self.checkIntegerParam(widget, 'height', 100, -100, 0, conv=str) 293 294 test_configure_highlightthickness = \ 295 StandardOptionsTests.test_configure_highlightthickness 296 297 def test_configure_image(self): 298 widget = self.create() 299 image = tkinter.PhotoImage(master=self.root, name='image1') 300 self.checkParam(widget, 'image', image, conv=str) 301 errmsg = 'image "spam" doesn\'t exist' 302 with self.assertRaises(tkinter.TclError) as cm: 303 widget['image'] = 'spam' 304 if errmsg is not None: 305 self.assertEqual(str(cm.exception), errmsg) 306 with self.assertRaises(tkinter.TclError) as cm: 307 widget.configure({'image': 'spam'}) 308 if errmsg is not None: 309 self.assertEqual(str(cm.exception), errmsg) 310 311 def test_configure_menu(self): 312 widget = self.create() 313 menu = tkinter.Menu(widget, name='menu') 314 self.checkParam(widget, 'menu', menu, eq=widget_eq) 315 menu.destroy() 316 317 def test_configure_padx(self): 318 widget = self.create() 319 self.checkPixelsParam(widget, 'padx', 3, 4.4, 5.6, '12m') 320 self.checkParam(widget, 'padx', -2, expected=0) 321 322 def test_configure_pady(self): 323 widget = self.create() 324 self.checkPixelsParam(widget, 'pady', 3, 4.4, 5.6, '12m') 325 self.checkParam(widget, 'pady', -2, expected=0) 326 327 def test_configure_width(self): 328 widget = self.create() 329 self.checkIntegerParam(widget, 'width', 402, -402, 0, conv=str) 330 331 332class OptionMenuTest(MenubuttonTest, unittest.TestCase): 333 334 def create(self, default='b', values=('a', 'b', 'c'), **kwargs): 335 return tkinter.OptionMenu(self.root, None, default, *values, **kwargs) 336 337 def test_bad_kwarg(self): 338 with self.assertRaisesRegex(TclError, r"^unknown option -image$"): 339 tkinter.OptionMenu(self.root, None, 'b', image='') 340 341 342@add_standard_options(IntegerSizeTests, StandardOptionsTests) 343class EntryTest(AbstractWidgetTest, unittest.TestCase): 344 OPTIONS = ( 345 'background', 'borderwidth', 'cursor', 346 'disabledbackground', 'disabledforeground', 347 'exportselection', 'font', 'foreground', 348 'highlightbackground', 'highlightcolor', 'highlightthickness', 349 'insertbackground', 'insertborderwidth', 350 'insertofftime', 'insertontime', 'insertwidth', 351 'invalidcommand', 'justify', 'readonlybackground', 'relief', 352 'selectbackground', 'selectborderwidth', 'selectforeground', 353 'show', 'state', 'takefocus', 'textvariable', 354 'validate', 'validatecommand', 'width', 'xscrollcommand', 355 ) 356 357 def create(self, **kwargs): 358 return tkinter.Entry(self.root, **kwargs) 359 360 def test_configure_disabledbackground(self): 361 widget = self.create() 362 self.checkColorParam(widget, 'disabledbackground') 363 364 def test_configure_insertborderwidth(self): 365 widget = self.create(insertwidth=100) 366 self.checkPixelsParam(widget, 'insertborderwidth', 367 0, 1.3, 2.6, 6, -2, '10p') 368 # insertborderwidth is bounded above by a half of insertwidth. 369 self.checkParam(widget, 'insertborderwidth', 60, expected=100//2) 370 371 def test_configure_insertwidth(self): 372 widget = self.create() 373 self.checkPixelsParam(widget, 'insertwidth', 1.3, 3.6, '10p') 374 self.checkParam(widget, 'insertwidth', 0.1, expected=2) 375 self.checkParam(widget, 'insertwidth', -2, expected=2) 376 self.checkParam(widget, 'insertwidth', 0.9, expected=1) 377 378 def test_configure_invalidcommand(self): 379 widget = self.create() 380 self.checkCommandParam(widget, 'invalidcommand') 381 self.checkCommandParam(widget, 'invcmd') 382 383 def test_configure_readonlybackground(self): 384 widget = self.create() 385 self.checkColorParam(widget, 'readonlybackground') 386 387 def test_configure_show(self): 388 widget = self.create() 389 self.checkParam(widget, 'show', '*') 390 self.checkParam(widget, 'show', '') 391 self.checkParam(widget, 'show', ' ') 392 393 def test_configure_state(self): 394 widget = self.create() 395 self.checkEnumParam(widget, 'state', 396 'disabled', 'normal', 'readonly') 397 398 def test_configure_validate(self): 399 widget = self.create() 400 self.checkEnumParam(widget, 'validate', 401 'all', 'key', 'focus', 'focusin', 'focusout', 'none') 402 403 def test_configure_validatecommand(self): 404 widget = self.create() 405 self.checkCommandParam(widget, 'validatecommand') 406 self.checkCommandParam(widget, 'vcmd') 407 408 def test_selection_methods(self): 409 widget = self.create() 410 widget.insert(0, '12345') 411 self.assertFalse(widget.selection_present()) 412 widget.selection_range(0, 'end') 413 self.assertEqual(widget.selection_get(), '12345') 414 self.assertTrue(widget.selection_present()) 415 widget.selection_from(1) 416 widget.selection_to(2) 417 self.assertEqual(widget.selection_get(), '2') 418 widget.selection_range(3, 4) 419 self.assertEqual(widget.selection_get(), '4') 420 widget.selection_clear() 421 self.assertFalse(widget.selection_present()) 422 widget.selection_range(0, 'end') 423 widget.selection_adjust(4) 424 self.assertEqual(widget.selection_get(), '1234') 425 widget.selection_adjust(1) 426 self.assertEqual(widget.selection_get(), '234') 427 widget.selection_adjust(5) 428 self.assertEqual(widget.selection_get(), '2345') 429 widget.selection_adjust(0) 430 self.assertEqual(widget.selection_get(), '12345') 431 widget.selection_adjust(0) 432 433 434@add_standard_options(StandardOptionsTests) 435class SpinboxTest(EntryTest, unittest.TestCase): 436 OPTIONS = ( 437 'activebackground', 'background', 'borderwidth', 438 'buttonbackground', 'buttoncursor', 'buttondownrelief', 'buttonuprelief', 439 'command', 'cursor', 'disabledbackground', 'disabledforeground', 440 'exportselection', 'font', 'foreground', 'format', 'from', 441 'highlightbackground', 'highlightcolor', 'highlightthickness', 442 'increment', 443 'insertbackground', 'insertborderwidth', 444 'insertofftime', 'insertontime', 'insertwidth', 445 'invalidcommand', 'justify', 'relief', 'readonlybackground', 446 'repeatdelay', 'repeatinterval', 447 'selectbackground', 'selectborderwidth', 'selectforeground', 448 'state', 'takefocus', 'textvariable', 'to', 449 'validate', 'validatecommand', 'values', 450 'width', 'wrap', 'xscrollcommand', 451 ) 452 453 def create(self, **kwargs): 454 return tkinter.Spinbox(self.root, **kwargs) 455 456 test_configure_show = None 457 458 def test_configure_buttonbackground(self): 459 widget = self.create() 460 self.checkColorParam(widget, 'buttonbackground') 461 462 def test_configure_buttoncursor(self): 463 widget = self.create() 464 self.checkCursorParam(widget, 'buttoncursor') 465 466 def test_configure_buttondownrelief(self): 467 widget = self.create() 468 self.checkReliefParam(widget, 'buttondownrelief') 469 470 def test_configure_buttonuprelief(self): 471 widget = self.create() 472 self.checkReliefParam(widget, 'buttonuprelief') 473 474 def test_configure_format(self): 475 widget = self.create() 476 self.checkParam(widget, 'format', '%2f') 477 self.checkParam(widget, 'format', '%2.2f') 478 self.checkParam(widget, 'format', '%.2f') 479 self.checkParam(widget, 'format', '%2.f') 480 self.checkInvalidParam(widget, 'format', '%2e-1f') 481 self.checkInvalidParam(widget, 'format', '2.2') 482 self.checkInvalidParam(widget, 'format', '%2.-2f') 483 self.checkParam(widget, 'format', '%-2.02f') 484 self.checkParam(widget, 'format', '% 2.02f') 485 self.checkParam(widget, 'format', '% -2.200f') 486 self.checkParam(widget, 'format', '%09.200f') 487 self.checkInvalidParam(widget, 'format', '%d') 488 489 def test_configure_from(self): 490 widget = self.create() 491 self.checkParam(widget, 'to', 100.0) 492 self.checkFloatParam(widget, 'from', -10, 10.2, 11.7) 493 self.checkInvalidParam(widget, 'from', 200, 494 errmsg='-to value must be greater than -from value') 495 496 def test_configure_increment(self): 497 widget = self.create() 498 self.checkFloatParam(widget, 'increment', -1, 1, 10.2, 12.8, 0) 499 500 def test_configure_to(self): 501 widget = self.create() 502 self.checkParam(widget, 'from', -100.0) 503 self.checkFloatParam(widget, 'to', -10, 10.2, 11.7) 504 self.checkInvalidParam(widget, 'to', -200, 505 errmsg='-to value must be greater than -from value') 506 507 def test_configure_values(self): 508 # XXX 509 widget = self.create() 510 self.assertEqual(widget['values'], '') 511 self.checkParam(widget, 'values', 'mon tue wed thur') 512 self.checkParam(widget, 'values', ('mon', 'tue', 'wed', 'thur'), 513 expected='mon tue wed thur') 514 self.checkParam(widget, 'values', (42, 3.14, '', 'any string'), 515 expected='42 3.14 {} {any string}') 516 self.checkParam(widget, 'values', '') 517 518 def test_configure_wrap(self): 519 widget = self.create() 520 self.checkBooleanParam(widget, 'wrap') 521 522 def test_bbox(self): 523 widget = self.create() 524 self.assertIsBoundingBox(widget.bbox(0)) 525 self.assertRaises(tkinter.TclError, widget.bbox, 'noindex') 526 self.assertRaises(tkinter.TclError, widget.bbox, None) 527 self.assertRaises(TypeError, widget.bbox) 528 self.assertRaises(TypeError, widget.bbox, 0, 1) 529 530 def test_selection_methods(self): 531 widget = self.create() 532 widget.insert(0, '12345') 533 self.assertFalse(widget.selection_present()) 534 widget.selection_range(0, 'end') 535 self.assertEqual(widget.selection_get(), '12345') 536 self.assertTrue(widget.selection_present()) 537 widget.selection_from(1) 538 widget.selection_to(2) 539 self.assertEqual(widget.selection_get(), '2') 540 widget.selection_range(3, 4) 541 self.assertEqual(widget.selection_get(), '4') 542 widget.selection_clear() 543 self.assertFalse(widget.selection_present()) 544 widget.selection_range(0, 'end') 545 widget.selection_adjust(4) 546 self.assertEqual(widget.selection_get(), '1234') 547 widget.selection_adjust(1) 548 self.assertEqual(widget.selection_get(), '234') 549 widget.selection_adjust(5) 550 self.assertEqual(widget.selection_get(), '2345') 551 widget.selection_adjust(0) 552 self.assertEqual(widget.selection_get(), '12345') 553 554 def test_selection_element(self): 555 widget = self.create() 556 self.assertEqual(widget.selection_element(), "none") 557 widget.selection_element("buttonup") 558 self.assertEqual(widget.selection_element(), "buttonup") 559 widget.selection_element("buttondown") 560 self.assertEqual(widget.selection_element(), "buttondown") 561 562 563@add_standard_options(StandardOptionsTests) 564class TextTest(AbstractWidgetTest, unittest.TestCase): 565 OPTIONS = ( 566 'autoseparators', 'background', 'blockcursor', 'borderwidth', 567 'cursor', 'endline', 'exportselection', 568 'font', 'foreground', 'height', 569 'highlightbackground', 'highlightcolor', 'highlightthickness', 570 'inactiveselectbackground', 'insertbackground', 'insertborderwidth', 571 'insertofftime', 'insertontime', 'insertunfocussed', 'insertwidth', 572 'maxundo', 'padx', 'pady', 'relief', 573 'selectbackground', 'selectborderwidth', 'selectforeground', 574 'setgrid', 'spacing1', 'spacing2', 'spacing3', 'startline', 'state', 575 'tabs', 'tabstyle', 'takefocus', 'undo', 'width', 'wrap', 576 'xscrollcommand', 'yscrollcommand', 577 ) 578 579 def create(self, **kwargs): 580 return tkinter.Text(self.root, **kwargs) 581 582 def test_configure_autoseparators(self): 583 widget = self.create() 584 self.checkBooleanParam(widget, 'autoseparators') 585 586 def test_configure_blockcursor(self): 587 widget = self.create() 588 self.checkBooleanParam(widget, 'blockcursor') 589 590 def test_configure_endline(self): 591 widget = self.create() 592 text = '\n'.join('Line %d' for i in range(100)) 593 widget.insert('end', text) 594 self.checkParam(widget, 'endline', 200, expected='') 595 self.checkParam(widget, 'endline', -10, expected='') 596 self.checkInvalidParam(widget, 'endline', 'spam', 597 errmsg='expected integer but got "spam"') 598 self.checkParam(widget, 'endline', 50) 599 self.checkParam(widget, 'startline', 15) 600 self.checkInvalidParam(widget, 'endline', 10, 601 errmsg='-startline must be less than or equal to -endline') 602 603 def test_configure_height(self): 604 widget = self.create() 605 self.checkPixelsParam(widget, 'height', 100, 101.2, 102.6, '3c') 606 self.checkParam(widget, 'height', -100, expected=1) 607 self.checkParam(widget, 'height', 0, expected=1) 608 609 def test_configure_maxundo(self): 610 widget = self.create() 611 self.checkIntegerParam(widget, 'maxundo', 0, 5, -1) 612 613 def test_configure_inactiveselectbackground(self): 614 widget = self.create() 615 self.checkColorParam(widget, 'inactiveselectbackground') 616 617 @requires_tcl(8, 6) 618 def test_configure_insertunfocussed(self): 619 widget = self.create() 620 self.checkEnumParam(widget, 'insertunfocussed', 621 'hollow', 'none', 'solid') 622 623 def test_configure_selectborderwidth(self): 624 widget = self.create() 625 self.checkPixelsParam(widget, 'selectborderwidth', 626 1.3, 2.6, -2, '10p', conv=False) 627 628 def test_configure_spacing1(self): 629 widget = self.create() 630 self.checkPixelsParam(widget, 'spacing1', 20, 21.4, 22.6, '0.5c') 631 self.checkParam(widget, 'spacing1', -5, expected=0) 632 633 def test_configure_spacing2(self): 634 widget = self.create() 635 self.checkPixelsParam(widget, 'spacing2', 5, 6.4, 7.6, '0.1c') 636 self.checkParam(widget, 'spacing2', -1, expected=0) 637 638 def test_configure_spacing3(self): 639 widget = self.create() 640 self.checkPixelsParam(widget, 'spacing3', 20, 21.4, 22.6, '0.5c') 641 self.checkParam(widget, 'spacing3', -10, expected=0) 642 643 def test_configure_startline(self): 644 widget = self.create() 645 text = '\n'.join('Line %d' for i in range(100)) 646 widget.insert('end', text) 647 self.checkParam(widget, 'startline', 200, expected='') 648 self.checkParam(widget, 'startline', -10, expected='') 649 self.checkInvalidParam(widget, 'startline', 'spam', 650 errmsg='expected integer but got "spam"') 651 self.checkParam(widget, 'startline', 10) 652 self.checkParam(widget, 'endline', 50) 653 self.checkInvalidParam(widget, 'startline', 70, 654 errmsg='-startline must be less than or equal to -endline') 655 656 def test_configure_state(self): 657 widget = self.create() 658 self.checkEnumParam(widget, 'state', 'disabled', 'normal') 659 660 def test_configure_tabs(self): 661 widget = self.create() 662 self.checkParam(widget, 'tabs', (10.2, 20.7, '1i', '2i')) 663 self.checkParam(widget, 'tabs', '10.2 20.7 1i 2i', 664 expected=('10.2', '20.7', '1i', '2i')) 665 self.checkParam(widget, 'tabs', '2c left 4c 6c center', 666 expected=('2c', 'left', '4c', '6c', 'center')) 667 self.checkInvalidParam(widget, 'tabs', 'spam', 668 errmsg='bad screen distance "spam"') 669 670 def test_configure_tabstyle(self): 671 widget = self.create() 672 self.checkEnumParam(widget, 'tabstyle', 'tabular', 'wordprocessor') 673 674 def test_configure_undo(self): 675 widget = self.create() 676 self.checkBooleanParam(widget, 'undo') 677 678 def test_configure_width(self): 679 widget = self.create() 680 self.checkIntegerParam(widget, 'width', 402) 681 self.checkParam(widget, 'width', -402, expected=1) 682 self.checkParam(widget, 'width', 0, expected=1) 683 684 def test_configure_wrap(self): 685 widget = self.create() 686 self.checkEnumParam(widget, 'wrap', 'char', 'none', 'word') 687 688 def test_bbox(self): 689 widget = self.create() 690 self.assertIsBoundingBox(widget.bbox('1.1')) 691 self.assertIsNone(widget.bbox('end')) 692 self.assertRaises(tkinter.TclError, widget.bbox, 'noindex') 693 self.assertRaises(tkinter.TclError, widget.bbox, None) 694 self.assertRaises(TypeError, widget.bbox) 695 self.assertRaises(TypeError, widget.bbox, '1.1', 'end') 696 697 698@add_standard_options(PixelSizeTests, StandardOptionsTests) 699class CanvasTest(AbstractWidgetTest, unittest.TestCase): 700 OPTIONS = ( 701 'background', 'borderwidth', 702 'closeenough', 'confine', 'cursor', 'height', 703 'highlightbackground', 'highlightcolor', 'highlightthickness', 704 'insertbackground', 'insertborderwidth', 705 'insertofftime', 'insertontime', 'insertwidth', 706 'offset', 'relief', 'scrollregion', 707 'selectbackground', 'selectborderwidth', 'selectforeground', 708 'state', 'takefocus', 709 'xscrollcommand', 'xscrollincrement', 710 'yscrollcommand', 'yscrollincrement', 'width', 711 ) 712 713 _conv_pixels = round 714 _stringify = True 715 716 def create(self, **kwargs): 717 return tkinter.Canvas(self.root, **kwargs) 718 719 def test_configure_closeenough(self): 720 widget = self.create() 721 self.checkFloatParam(widget, 'closeenough', 24, 2.4, 3.6, -3, 722 conv=float) 723 724 def test_configure_confine(self): 725 widget = self.create() 726 self.checkBooleanParam(widget, 'confine') 727 728 def test_configure_offset(self): 729 widget = self.create() 730 self.assertEqual(widget['offset'], '0,0') 731 self.checkParams(widget, 'offset', 732 'n', 'ne', 'e', 'se', 's', 'sw', 'w', 'nw', 'center') 733 self.checkParam(widget, 'offset', '10,20') 734 self.checkParam(widget, 'offset', '#5,6') 735 self.checkInvalidParam(widget, 'offset', 'spam') 736 737 def test_configure_scrollregion(self): 738 widget = self.create() 739 self.checkParam(widget, 'scrollregion', '0 0 200 150') 740 self.checkParam(widget, 'scrollregion', (0, 0, 200, 150), 741 expected='0 0 200 150') 742 self.checkParam(widget, 'scrollregion', '') 743 self.checkInvalidParam(widget, 'scrollregion', 'spam', 744 errmsg='bad scrollRegion "spam"') 745 self.checkInvalidParam(widget, 'scrollregion', (0, 0, 200, 'spam')) 746 self.checkInvalidParam(widget, 'scrollregion', (0, 0, 200)) 747 self.checkInvalidParam(widget, 'scrollregion', (0, 0, 200, 150, 0)) 748 749 def test_configure_state(self): 750 widget = self.create() 751 self.checkEnumParam(widget, 'state', 'disabled', 'normal', 752 errmsg='bad state value "{}": must be normal or disabled') 753 754 def test_configure_xscrollincrement(self): 755 widget = self.create() 756 self.checkPixelsParam(widget, 'xscrollincrement', 757 40, 0, 41.2, 43.6, -40, '0.5i') 758 759 def test_configure_yscrollincrement(self): 760 widget = self.create() 761 self.checkPixelsParam(widget, 'yscrollincrement', 762 10, 0, 11.2, 13.6, -10, '0.1i') 763 764 def _test_option_joinstyle(self, c, factory): 765 for joinstyle in 'bevel', 'miter', 'round': 766 i = factory(joinstyle=joinstyle) 767 self.assertEqual(c.itemcget(i, 'joinstyle'), joinstyle) 768 self.assertRaises(TclError, factory, joinstyle='spam') 769 770 def _test_option_smooth(self, c, factory): 771 for smooth in 1, True, '1', 'true', 'yes', 'on': 772 i = factory(smooth=smooth) 773 self.assertEqual(c.itemcget(i, 'smooth'), 'true') 774 for smooth in 0, False, '0', 'false', 'no', 'off': 775 i = factory(smooth=smooth) 776 self.assertEqual(c.itemcget(i, 'smooth'), '0') 777 i = factory(smooth=True, splinestep=30) 778 self.assertEqual(c.itemcget(i, 'smooth'), 'true') 779 self.assertEqual(c.itemcget(i, 'splinestep'), '30') 780 i = factory(smooth='raw', splinestep=30) 781 self.assertEqual(c.itemcget(i, 'smooth'), 'raw') 782 self.assertEqual(c.itemcget(i, 'splinestep'), '30') 783 self.assertRaises(TclError, factory, smooth='spam') 784 785 def test_create_rectangle(self): 786 c = self.create() 787 i1 = c.create_rectangle(20, 30, 60, 10) 788 self.assertEqual(c.coords(i1), [20.0, 10.0, 60.0, 30.0]) 789 self.assertEqual(c.bbox(i1), (19, 9, 61, 31)) 790 791 i2 = c.create_rectangle([21, 31, 61, 11]) 792 self.assertEqual(c.coords(i2), [21.0, 11.0, 61.0, 31.0]) 793 self.assertEqual(c.bbox(i2), (20, 10, 62, 32)) 794 795 i3 = c.create_rectangle((22, 32), (62, 12)) 796 self.assertEqual(c.coords(i3), [22.0, 12.0, 62.0, 32.0]) 797 self.assertEqual(c.bbox(i3), (21, 11, 63, 33)) 798 799 i4 = c.create_rectangle([(23, 33), (63, 13)]) 800 self.assertEqual(c.coords(i4), [23.0, 13.0, 63.0, 33.0]) 801 self.assertEqual(c.bbox(i4), (22, 12, 64, 34)) 802 803 self.assertRaises(TclError, c.create_rectangle, 20, 30, 60) 804 self.assertRaises(TclError, c.create_rectangle, [20, 30, 60]) 805 self.assertRaises(TclError, c.create_rectangle, 20, 30, 40, 50, 60, 10) 806 self.assertRaises(TclError, c.create_rectangle, [20, 30, 40, 50, 60, 10]) 807 self.assertRaises(TclError, c.create_rectangle, 20, 30) 808 self.assertRaises(TclError, c.create_rectangle, [20, 30]) 809 self.assertRaises(IndexError, c.create_rectangle) 810 self.assertRaises(IndexError, c.create_rectangle, []) 811 812 def test_create_line(self): 813 c = self.create() 814 i1 = c.create_line(20, 30, 40, 50, 60, 10) 815 self.assertEqual(c.coords(i1), [20.0, 30.0, 40.0, 50.0, 60.0, 10.0]) 816 self.assertEqual(c.bbox(i1), (18, 8, 62, 52)) 817 self.assertEqual(c.itemcget(i1, 'arrow'), 'none') 818 self.assertEqual(c.itemcget(i1, 'arrowshape'), '8 10 3') 819 self.assertEqual(c.itemcget(i1, 'capstyle'), 'butt') 820 self.assertEqual(c.itemcget(i1, 'joinstyle'), 'round') 821 self.assertEqual(c.itemcget(i1, 'smooth'), '0') 822 self.assertEqual(c.itemcget(i1, 'splinestep'), '12') 823 824 i2 = c.create_line([21, 31, 41, 51, 61, 11]) 825 self.assertEqual(c.coords(i2), [21.0, 31.0, 41.0, 51.0, 61.0, 11.0]) 826 self.assertEqual(c.bbox(i2), (19, 9, 63, 53)) 827 828 i3 = c.create_line((22, 32), (42, 52), (62, 12)) 829 self.assertEqual(c.coords(i3), [22.0, 32.0, 42.0, 52.0, 62.0, 12.0]) 830 self.assertEqual(c.bbox(i3), (20, 10, 64, 54)) 831 832 i4 = c.create_line([(23, 33), (43, 53), (63, 13)]) 833 self.assertEqual(c.coords(i4), [23.0, 33.0, 43.0, 53.0, 63.0, 13.0]) 834 self.assertEqual(c.bbox(i4), (21, 11, 65, 55)) 835 836 self.assertRaises(TclError, c.create_line, 20, 30, 60) 837 self.assertRaises(TclError, c.create_line, [20, 30, 60]) 838 self.assertRaises(TclError, c.create_line, 20, 30) 839 self.assertRaises(TclError, c.create_line, [20, 30]) 840 self.assertRaises(IndexError, c.create_line) 841 self.assertRaises(IndexError, c.create_line, []) 842 843 for arrow in 'none', 'first', 'last', 'both': 844 i = c.create_line(20, 30, 60, 10, arrow=arrow) 845 self.assertEqual(c.itemcget(i, 'arrow'), arrow) 846 i = c.create_line(20, 30, 60, 10, arrow='first', arrowshape=[10, 15, 5]) 847 self.assertEqual(c.itemcget(i, 'arrowshape'), '10 15 5') 848 self.assertRaises(TclError, c.create_line, 20, 30, 60, 10, arrow='spam') 849 850 for capstyle in 'butt', 'projecting', 'round': 851 i = c.create_line(20, 30, 60, 10, capstyle=capstyle) 852 self.assertEqual(c.itemcget(i, 'capstyle'), capstyle) 853 self.assertRaises(TclError, c.create_line, 20, 30, 60, 10, capstyle='spam') 854 855 self._test_option_joinstyle(c, 856 lambda **kwargs: c.create_line(20, 30, 40, 50, 60, 10, **kwargs)) 857 self._test_option_smooth(c, 858 lambda **kwargs: c.create_line(20, 30, 60, 10, **kwargs)) 859 860 def test_create_polygon(self): 861 c = self.create() 862 i1 = c.create_polygon(20, 30, 40, 50, 60, 10) 863 self.assertEqual(c.coords(i1), [20.0, 30.0, 40.0, 50.0, 60.0, 10.0]) 864 self.assertEqual(c.bbox(i1), (19, 9, 61, 51)) 865 self.assertEqual(c.itemcget(i1, 'joinstyle'), 'round') 866 self.assertEqual(c.itemcget(i1, 'smooth'), '0') 867 self.assertEqual(c.itemcget(i1, 'splinestep'), '12') 868 869 i2 = c.create_polygon([21, 31, 41, 51, 61, 11]) 870 self.assertEqual(c.coords(i2), [21.0, 31.0, 41.0, 51.0, 61.0, 11.0]) 871 self.assertEqual(c.bbox(i2), (20, 10, 62, 52)) 872 873 i3 = c.create_polygon((22, 32), (42, 52), (62, 12)) 874 self.assertEqual(c.coords(i3), [22.0, 32.0, 42.0, 52.0, 62.0, 12.0]) 875 self.assertEqual(c.bbox(i3), (21, 11, 63, 53)) 876 877 i4 = c.create_polygon([(23, 33), (43, 53), (63, 13)]) 878 self.assertEqual(c.coords(i4), [23.0, 33.0, 43.0, 53.0, 63.0, 13.0]) 879 self.assertEqual(c.bbox(i4), (22, 12, 64, 54)) 880 881 self.assertRaises(TclError, c.create_polygon, 20, 30, 60) 882 self.assertRaises(TclError, c.create_polygon, [20, 30, 60]) 883 self.assertRaises(IndexError, c.create_polygon) 884 self.assertRaises(IndexError, c.create_polygon, []) 885 886 self._test_option_joinstyle(c, 887 lambda **kwargs: c.create_polygon(20, 30, 40, 50, 60, 10, **kwargs)) 888 self._test_option_smooth(c, 889 lambda **kwargs: c.create_polygon(20, 30, 40, 50, 60, 10, **kwargs)) 890 891 def test_coords(self): 892 c = self.create() 893 i = c.create_line(20, 30, 40, 50, 60, 10, tags='x') 894 self.assertEqual(c.coords(i), [20.0, 30.0, 40.0, 50.0, 60.0, 10.0]) 895 self.assertEqual(c.coords('x'), [20.0, 30.0, 40.0, 50.0, 60.0, 10.0]) 896 self.assertEqual(c.bbox(i), (18, 8, 62, 52)) 897 898 c.coords(i, 50, 60, 70, 80, 90, 40) 899 self.assertEqual(c.coords(i), [50.0, 60.0, 70.0, 80.0, 90.0, 40.0]) 900 self.assertEqual(c.bbox(i), (48, 38, 92, 82)) 901 902 c.coords(i, [21, 31, 41, 51, 61, 11]) 903 self.assertEqual(c.coords(i), [21.0, 31.0, 41.0, 51.0, 61.0, 11.0]) 904 905 c.coords(i, 20, 30, 60, 10) 906 self.assertEqual(c.coords(i), [20.0, 30.0, 60.0, 10.0]) 907 self.assertEqual(c.bbox(i), (18, 8, 62, 32)) 908 909 self.assertRaises(TclError, c.coords, i, 20, 30, 60) 910 self.assertRaises(TclError, c.coords, i, [20, 30, 60]) 911 self.assertRaises(TclError, c.coords, i, 20, 30) 912 self.assertRaises(TclError, c.coords, i, [20, 30]) 913 914 c.coords(i, '20', '30c', '60i', '10p') 915 coords = c.coords(i) 916 self.assertIsInstance(coords, list) 917 self.assertEqual(len(coords), 4) 918 self.assertEqual(coords[0], 20) 919 for i in range(4): 920 self.assertIsInstance(coords[i], float) 921 922 @requires_tcl(8, 6) 923 def test_moveto(self): 924 widget = self.create() 925 i1 = widget.create_rectangle(1, 1, 20, 20, tags='group') 926 i2 = widget.create_rectangle(30, 30, 50, 70, tags='group') 927 x1, y1, _, _ = widget.bbox(i1) 928 x2, y2, _, _ = widget.bbox(i2) 929 widget.moveto('group', 200, 100) 930 x1_2, y1_2, _, _ = widget.bbox(i1) 931 x2_2, y2_2, _, _ = widget.bbox(i2) 932 self.assertEqual(x1_2, 200) 933 self.assertEqual(y1_2, 100) 934 self.assertEqual(x2 - x1, x2_2 - x1_2) 935 self.assertEqual(y2 - y1, y2_2 - y1_2) 936 widget.tag_lower(i2, i1) 937 widget.moveto('group', y=50) 938 x1_3, y1_3, _, _ = widget.bbox(i1) 939 x2_3, y2_3, _, _ = widget.bbox(i2) 940 self.assertEqual(y2_3, 50) 941 self.assertEqual(x2_3, x2_2) 942 self.assertEqual(x2_2 - x1_2, x2_3 - x1_3) 943 self.assertEqual(y2_2 - y1_2, y2_3 - y1_3) 944 945 946@add_standard_options(IntegerSizeTests, StandardOptionsTests) 947class ListboxTest(AbstractWidgetTest, unittest.TestCase): 948 OPTIONS = ( 949 'activestyle', 'background', 'borderwidth', 'cursor', 950 'disabledforeground', 'exportselection', 951 'font', 'foreground', 'height', 952 'highlightbackground', 'highlightcolor', 'highlightthickness', 953 'justify', 'listvariable', 'relief', 954 'selectbackground', 'selectborderwidth', 'selectforeground', 955 'selectmode', 'setgrid', 'state', 956 'takefocus', 'width', 'xscrollcommand', 'yscrollcommand', 957 ) 958 959 def create(self, **kwargs): 960 return tkinter.Listbox(self.root, **kwargs) 961 962 def test_configure_activestyle(self): 963 widget = self.create() 964 self.checkEnumParam(widget, 'activestyle', 965 'dotbox', 'none', 'underline') 966 967 test_configure_justify = requires_tcl(8, 6, 5)(StandardOptionsTests.test_configure_justify) 968 969 def test_configure_listvariable(self): 970 widget = self.create() 971 var = tkinter.DoubleVar(self.root) 972 self.checkVariableParam(widget, 'listvariable', var) 973 974 def test_configure_selectmode(self): 975 widget = self.create() 976 self.checkParam(widget, 'selectmode', 'single') 977 self.checkParam(widget, 'selectmode', 'browse') 978 self.checkParam(widget, 'selectmode', 'multiple') 979 self.checkParam(widget, 'selectmode', 'extended') 980 981 def test_configure_state(self): 982 widget = self.create() 983 self.checkEnumParam(widget, 'state', 'disabled', 'normal') 984 985 def test_itemconfigure(self): 986 widget = self.create() 987 with self.assertRaisesRegex(TclError, 'item number "0" out of range'): 988 widget.itemconfigure(0) 989 colors = 'red orange yellow green blue white violet'.split() 990 widget.insert('end', *colors) 991 for i, color in enumerate(colors): 992 widget.itemconfigure(i, background=color) 993 with self.assertRaises(TypeError): 994 widget.itemconfigure() 995 with self.assertRaisesRegex(TclError, 'bad listbox index "red"'): 996 widget.itemconfigure('red') 997 self.assertEqual(widget.itemconfigure(0, 'background'), 998 ('background', 'background', 'Background', '', 'red')) 999 self.assertEqual(widget.itemconfigure('end', 'background'), 1000 ('background', 'background', 'Background', '', 'violet')) 1001 self.assertEqual(widget.itemconfigure('@0,0', 'background'), 1002 ('background', 'background', 'Background', '', 'red')) 1003 1004 d = widget.itemconfigure(0) 1005 self.assertIsInstance(d, dict) 1006 for k, v in d.items(): 1007 self.assertIn(len(v), (2, 5)) 1008 if len(v) == 5: 1009 self.assertEqual(v, widget.itemconfigure(0, k)) 1010 self.assertEqual(v[4], widget.itemcget(0, k)) 1011 1012 def check_itemconfigure(self, name, value): 1013 widget = self.create() 1014 widget.insert('end', 'a', 'b', 'c', 'd') 1015 widget.itemconfigure(0, **{name: value}) 1016 self.assertEqual(widget.itemconfigure(0, name)[4], value) 1017 self.assertEqual(widget.itemcget(0, name), value) 1018 with self.assertRaisesRegex(TclError, 'unknown color name "spam"'): 1019 widget.itemconfigure(0, **{name: 'spam'}) 1020 1021 def test_itemconfigure_background(self): 1022 self.check_itemconfigure('background', '#ff0000') 1023 1024 def test_itemconfigure_bg(self): 1025 self.check_itemconfigure('bg', '#ff0000') 1026 1027 def test_itemconfigure_fg(self): 1028 self.check_itemconfigure('fg', '#110022') 1029 1030 def test_itemconfigure_foreground(self): 1031 self.check_itemconfigure('foreground', '#110022') 1032 1033 def test_itemconfigure_selectbackground(self): 1034 self.check_itemconfigure('selectbackground', '#110022') 1035 1036 def test_itemconfigure_selectforeground(self): 1037 self.check_itemconfigure('selectforeground', '#654321') 1038 1039 def test_box(self): 1040 lb = self.create() 1041 lb.insert(0, *('el%d' % i for i in range(8))) 1042 lb.pack() 1043 self.assertIsBoundingBox(lb.bbox(0)) 1044 self.assertIsNone(lb.bbox(-1)) 1045 self.assertIsNone(lb.bbox(10)) 1046 self.assertRaises(TclError, lb.bbox, 'noindex') 1047 self.assertRaises(TclError, lb.bbox, None) 1048 self.assertRaises(TypeError, lb.bbox) 1049 self.assertRaises(TypeError, lb.bbox, 0, 1) 1050 1051 def test_curselection(self): 1052 lb = self.create() 1053 lb.insert(0, *('el%d' % i for i in range(8))) 1054 lb.selection_clear(0, tkinter.END) 1055 lb.selection_set(2, 4) 1056 lb.selection_set(6) 1057 self.assertEqual(lb.curselection(), (2, 3, 4, 6)) 1058 self.assertRaises(TypeError, lb.curselection, 0) 1059 1060 def test_get(self): 1061 lb = self.create() 1062 lb.insert(0, *('el%d' % i for i in range(8))) 1063 self.assertEqual(lb.get(0), 'el0') 1064 self.assertEqual(lb.get(3), 'el3') 1065 self.assertEqual(lb.get('end'), 'el7') 1066 self.assertEqual(lb.get(8), '') 1067 self.assertEqual(lb.get(-1), '') 1068 self.assertEqual(lb.get(3, 5), ('el3', 'el4', 'el5')) 1069 self.assertEqual(lb.get(5, 'end'), ('el5', 'el6', 'el7')) 1070 self.assertEqual(lb.get(5, 0), ()) 1071 self.assertEqual(lb.get(0, 0), ('el0',)) 1072 self.assertRaises(TclError, lb.get, 'noindex') 1073 self.assertRaises(TclError, lb.get, None) 1074 self.assertRaises(TypeError, lb.get) 1075 self.assertRaises(TclError, lb.get, 'end', 'noindex') 1076 self.assertRaises(TypeError, lb.get, 1, 2, 3) 1077 self.assertRaises(TclError, lb.get, 2.4) 1078 1079 1080@add_standard_options(PixelSizeTests, StandardOptionsTests) 1081class ScaleTest(AbstractWidgetTest, unittest.TestCase): 1082 OPTIONS = ( 1083 'activebackground', 'background', 'bigincrement', 'borderwidth', 1084 'command', 'cursor', 'digits', 'font', 'foreground', 'from', 1085 'highlightbackground', 'highlightcolor', 'highlightthickness', 1086 'label', 'length', 'orient', 'relief', 1087 'repeatdelay', 'repeatinterval', 1088 'resolution', 'showvalue', 'sliderlength', 'sliderrelief', 'state', 1089 'takefocus', 'tickinterval', 'to', 'troughcolor', 'variable', 'width', 1090 ) 1091 default_orient = 'vertical' 1092 1093 def create(self, **kwargs): 1094 return tkinter.Scale(self.root, **kwargs) 1095 1096 def test_configure_bigincrement(self): 1097 widget = self.create() 1098 self.checkFloatParam(widget, 'bigincrement', 12.4, 23.6, -5) 1099 1100 def test_configure_digits(self): 1101 widget = self.create() 1102 self.checkIntegerParam(widget, 'digits', 5, 0) 1103 1104 def test_configure_from(self): 1105 widget = self.create() 1106 conv = float if get_tk_patchlevel() >= (8, 6, 10) else float_round 1107 self.checkFloatParam(widget, 'from', 100, 14.9, 15.1, conv=conv) 1108 1109 def test_configure_label(self): 1110 widget = self.create() 1111 self.checkParam(widget, 'label', 'any string') 1112 self.checkParam(widget, 'label', '') 1113 1114 def test_configure_length(self): 1115 widget = self.create() 1116 self.checkPixelsParam(widget, 'length', 130, 131.2, 135.6, '5i') 1117 1118 def test_configure_resolution(self): 1119 widget = self.create() 1120 self.checkFloatParam(widget, 'resolution', 4.2, 0, 6.7, -2) 1121 1122 def test_configure_showvalue(self): 1123 widget = self.create() 1124 self.checkBooleanParam(widget, 'showvalue') 1125 1126 def test_configure_sliderlength(self): 1127 widget = self.create() 1128 self.checkPixelsParam(widget, 'sliderlength', 1129 10, 11.2, 15.6, -3, '3m') 1130 1131 def test_configure_sliderrelief(self): 1132 widget = self.create() 1133 self.checkReliefParam(widget, 'sliderrelief') 1134 1135 def test_configure_tickinterval(self): 1136 widget = self.create() 1137 self.checkFloatParam(widget, 'tickinterval', 1, 4.3, 7.6, 0, 1138 conv=float_round) 1139 self.checkParam(widget, 'tickinterval', -2, expected=2, 1140 conv=float_round) 1141 1142 def test_configure_to(self): 1143 widget = self.create() 1144 self.checkFloatParam(widget, 'to', 300, 14.9, 15.1, -10, 1145 conv=float_round) 1146 1147 1148@add_standard_options(PixelSizeTests, StandardOptionsTests) 1149class ScrollbarTest(AbstractWidgetTest, unittest.TestCase): 1150 OPTIONS = ( 1151 'activebackground', 'activerelief', 1152 'background', 'borderwidth', 1153 'command', 'cursor', 'elementborderwidth', 1154 'highlightbackground', 'highlightcolor', 'highlightthickness', 1155 'jump', 'orient', 'relief', 1156 'repeatdelay', 'repeatinterval', 1157 'takefocus', 'troughcolor', 'width', 1158 ) 1159 _conv_pixels = round 1160 _stringify = True 1161 default_orient = 'vertical' 1162 1163 def create(self, **kwargs): 1164 return tkinter.Scrollbar(self.root, **kwargs) 1165 1166 def test_configure_activerelief(self): 1167 widget = self.create() 1168 self.checkReliefParam(widget, 'activerelief') 1169 1170 def test_configure_elementborderwidth(self): 1171 widget = self.create() 1172 self.checkPixelsParam(widget, 'elementborderwidth', 4.3, 5.6, -2, '1m') 1173 1174 def test_configure_orient(self): 1175 widget = self.create() 1176 self.checkEnumParam(widget, 'orient', 'vertical', 'horizontal', 1177 errmsg='bad orientation "{}": must be vertical or horizontal') 1178 1179 def test_activate(self): 1180 sb = self.create() 1181 for e in ('arrow1', 'slider', 'arrow2'): 1182 sb.activate(e) 1183 self.assertEqual(sb.activate(), e) 1184 sb.activate('') 1185 self.assertIsNone(sb.activate()) 1186 self.assertRaises(TypeError, sb.activate, 'arrow1', 'arrow2') 1187 1188 def test_set(self): 1189 sb = self.create() 1190 sb.set(0.2, 0.4) 1191 self.assertEqual(sb.get(), (0.2, 0.4)) 1192 self.assertRaises(TclError, sb.set, 'abc', 'def') 1193 self.assertRaises(TclError, sb.set, 0.6, 'def') 1194 self.assertRaises(TclError, sb.set, 0.6, None) 1195 self.assertRaises(TypeError, sb.set, 0.6) 1196 self.assertRaises(TypeError, sb.set, 0.6, 0.7, 0.8) 1197 1198 1199@add_standard_options(StandardOptionsTests) 1200class PanedWindowTest(AbstractWidgetTest, unittest.TestCase): 1201 OPTIONS = ( 1202 'background', 'borderwidth', 'cursor', 1203 'handlepad', 'handlesize', 'height', 1204 'opaqueresize', 'orient', 1205 'proxybackground', 'proxyborderwidth', 'proxyrelief', 1206 'relief', 1207 'sashcursor', 'sashpad', 'sashrelief', 'sashwidth', 1208 'showhandle', 'width', 1209 ) 1210 default_orient = 'horizontal' 1211 1212 def create(self, **kwargs): 1213 return tkinter.PanedWindow(self.root, **kwargs) 1214 1215 def test_configure_handlepad(self): 1216 widget = self.create() 1217 self.checkPixelsParam(widget, 'handlepad', 5, 6.4, 7.6, -3, '1m') 1218 1219 def test_configure_handlesize(self): 1220 widget = self.create() 1221 self.checkPixelsParam(widget, 'handlesize', 8, 9.4, 10.6, -3, '2m', 1222 conv=False) 1223 1224 def test_configure_height(self): 1225 widget = self.create() 1226 self.checkPixelsParam(widget, 'height', 100, 101.2, 102.6, -100, 0, '1i', 1227 conv=False) 1228 1229 def test_configure_opaqueresize(self): 1230 widget = self.create() 1231 self.checkBooleanParam(widget, 'opaqueresize') 1232 1233 @requires_tcl(8, 6, 5) 1234 def test_configure_proxybackground(self): 1235 widget = self.create() 1236 self.checkColorParam(widget, 'proxybackground') 1237 1238 @requires_tcl(8, 6, 5) 1239 def test_configure_proxyborderwidth(self): 1240 widget = self.create() 1241 self.checkPixelsParam(widget, 'proxyborderwidth', 1242 0, 1.3, 2.9, 6, -2, '10p', 1243 conv=False) 1244 1245 @requires_tcl(8, 6, 5) 1246 def test_configure_proxyrelief(self): 1247 widget = self.create() 1248 self.checkReliefParam(widget, 'proxyrelief') 1249 1250 def test_configure_sashcursor(self): 1251 widget = self.create() 1252 self.checkCursorParam(widget, 'sashcursor') 1253 1254 def test_configure_sashpad(self): 1255 widget = self.create() 1256 self.checkPixelsParam(widget, 'sashpad', 8, 1.3, 2.6, -2, '2m') 1257 1258 def test_configure_sashrelief(self): 1259 widget = self.create() 1260 self.checkReliefParam(widget, 'sashrelief') 1261 1262 def test_configure_sashwidth(self): 1263 widget = self.create() 1264 self.checkPixelsParam(widget, 'sashwidth', 10, 11.1, 15.6, -3, '1m', 1265 conv=False) 1266 1267 def test_configure_showhandle(self): 1268 widget = self.create() 1269 self.checkBooleanParam(widget, 'showhandle') 1270 1271 def test_configure_width(self): 1272 widget = self.create() 1273 self.checkPixelsParam(widget, 'width', 402, 403.4, 404.6, -402, 0, '5i', 1274 conv=False) 1275 1276 def create2(self): 1277 p = self.create() 1278 b = tkinter.Button(p) 1279 c = tkinter.Button(p) 1280 p.add(b) 1281 p.add(c) 1282 return p, b, c 1283 1284 def test_paneconfigure(self): 1285 p, b, c = self.create2() 1286 self.assertRaises(TypeError, p.paneconfigure) 1287 d = p.paneconfigure(b) 1288 self.assertIsInstance(d, dict) 1289 for k, v in d.items(): 1290 self.assertEqual(len(v), 5) 1291 self.assertEqual(v, p.paneconfigure(b, k)) 1292 self.assertEqual(v[4], p.panecget(b, k)) 1293 1294 def check_paneconfigure(self, p, b, name, value, expected): 1295 if not self.wantobjects: 1296 expected = str(expected) 1297 p.paneconfigure(b, **{name: value}) 1298 self.assertEqual(p.paneconfigure(b, name)[4], expected) 1299 self.assertEqual(p.panecget(b, name), expected) 1300 1301 def check_paneconfigure_bad(self, p, b, name, msg): 1302 with self.assertRaisesRegex(TclError, msg): 1303 p.paneconfigure(b, **{name: 'badValue'}) 1304 1305 def test_paneconfigure_after(self): 1306 p, b, c = self.create2() 1307 self.check_paneconfigure(p, b, 'after', c, str(c)) 1308 self.check_paneconfigure_bad(p, b, 'after', 1309 'bad window path name "badValue"') 1310 1311 def test_paneconfigure_before(self): 1312 p, b, c = self.create2() 1313 self.check_paneconfigure(p, b, 'before', c, str(c)) 1314 self.check_paneconfigure_bad(p, b, 'before', 1315 'bad window path name "badValue"') 1316 1317 def test_paneconfigure_height(self): 1318 p, b, c = self.create2() 1319 self.check_paneconfigure(p, b, 'height', 10, 10) 1320 self.check_paneconfigure_bad(p, b, 'height', 1321 'bad screen distance "badValue"') 1322 1323 def test_paneconfigure_hide(self): 1324 p, b, c = self.create2() 1325 self.check_paneconfigure(p, b, 'hide', False, 0) 1326 self.check_paneconfigure_bad(p, b, 'hide', 1327 'expected boolean value but got "badValue"') 1328 1329 def test_paneconfigure_minsize(self): 1330 p, b, c = self.create2() 1331 self.check_paneconfigure(p, b, 'minsize', 10, 10) 1332 self.check_paneconfigure_bad(p, b, 'minsize', 1333 'bad screen distance "badValue"') 1334 1335 def test_paneconfigure_padx(self): 1336 p, b, c = self.create2() 1337 self.check_paneconfigure(p, b, 'padx', 1.3, 1) 1338 self.check_paneconfigure_bad(p, b, 'padx', 1339 'bad screen distance "badValue"') 1340 1341 def test_paneconfigure_pady(self): 1342 p, b, c = self.create2() 1343 self.check_paneconfigure(p, b, 'pady', 1.3, 1) 1344 self.check_paneconfigure_bad(p, b, 'pady', 1345 'bad screen distance "badValue"') 1346 1347 def test_paneconfigure_sticky(self): 1348 p, b, c = self.create2() 1349 self.check_paneconfigure(p, b, 'sticky', 'nsew', 'nesw') 1350 self.check_paneconfigure_bad(p, b, 'sticky', 1351 'bad stickyness value "badValue": must ' 1352 'be a string containing zero or more of ' 1353 'n, e, s, and w') 1354 1355 def test_paneconfigure_stretch(self): 1356 p, b, c = self.create2() 1357 self.check_paneconfigure(p, b, 'stretch', 'alw', 'always') 1358 self.check_paneconfigure_bad(p, b, 'stretch', 1359 'bad stretch "badValue": must be ' 1360 'always, first, last, middle, or never') 1361 1362 def test_paneconfigure_width(self): 1363 p, b, c = self.create2() 1364 self.check_paneconfigure(p, b, 'width', 10, 10) 1365 self.check_paneconfigure_bad(p, b, 'width', 1366 'bad screen distance "badValue"') 1367 1368 1369@add_standard_options(StandardOptionsTests) 1370class MenuTest(AbstractWidgetTest, unittest.TestCase): 1371 OPTIONS = ( 1372 'activebackground', 'activeborderwidth', 'activeforeground', 1373 'background', 'borderwidth', 'cursor', 1374 'disabledforeground', 'font', 'foreground', 1375 'postcommand', 'relief', 'selectcolor', 'takefocus', 1376 'tearoff', 'tearoffcommand', 'title', 'type', 1377 ) 1378 _conv_pixels = False 1379 1380 def create(self, **kwargs): 1381 return tkinter.Menu(self.root, **kwargs) 1382 1383 def test_indexcommand_none(self): 1384 widget = self.create() 1385 i = widget.index('none') 1386 self.assertIsNone(i) 1387 1388 def test_configure_postcommand(self): 1389 widget = self.create() 1390 self.checkCommandParam(widget, 'postcommand') 1391 1392 def test_configure_tearoff(self): 1393 widget = self.create() 1394 self.checkBooleanParam(widget, 'tearoff') 1395 1396 def test_configure_tearoffcommand(self): 1397 widget = self.create() 1398 self.checkCommandParam(widget, 'tearoffcommand') 1399 1400 def test_configure_title(self): 1401 widget = self.create() 1402 self.checkParam(widget, 'title', 'any string') 1403 1404 def test_configure_type(self): 1405 widget = self.create() 1406 opts = ('normal, tearoff, or menubar' 1407 if widget.info_patchlevel() < (8, 7) else 1408 'menubar, normal, or tearoff') 1409 self.checkEnumParam( 1410 widget, 'type', 1411 'normal', 'tearoff', 'menubar', 1412 errmsg='bad type "{}": must be ' + opts, 1413 ) 1414 1415 def test_entryconfigure(self): 1416 m1 = self.create() 1417 m1.add_command(label='test') 1418 self.assertRaises(TypeError, m1.entryconfigure) 1419 with self.assertRaisesRegex(TclError, 'bad menu entry index "foo"'): 1420 m1.entryconfigure('foo') 1421 d = m1.entryconfigure(1) 1422 self.assertIsInstance(d, dict) 1423 for k, v in d.items(): 1424 self.assertIsInstance(k, str) 1425 self.assertIsInstance(v, tuple) 1426 self.assertEqual(len(v), 5) 1427 self.assertEqual(v[0], k) 1428 self.assertEqual(m1.entrycget(1, k), v[4]) 1429 m1.destroy() 1430 1431 def test_entryconfigure_label(self): 1432 m1 = self.create() 1433 m1.add_command(label='test') 1434 self.assertEqual(m1.entrycget(1, 'label'), 'test') 1435 m1.entryconfigure(1, label='changed') 1436 self.assertEqual(m1.entrycget(1, 'label'), 'changed') 1437 1438 def test_entryconfigure_variable(self): 1439 m1 = self.create() 1440 v1 = tkinter.BooleanVar(self.root) 1441 v2 = tkinter.BooleanVar(self.root) 1442 m1.add_checkbutton(variable=v1, onvalue=True, offvalue=False, 1443 label='Nonsense') 1444 self.assertEqual(str(m1.entrycget(1, 'variable')), str(v1)) 1445 m1.entryconfigure(1, variable=v2) 1446 self.assertEqual(str(m1.entrycget(1, 'variable')), str(v2)) 1447 1448 1449@add_standard_options(PixelSizeTests, StandardOptionsTests) 1450class MessageTest(AbstractWidgetTest, unittest.TestCase): 1451 OPTIONS = ( 1452 'anchor', 'aspect', 'background', 'borderwidth', 1453 'cursor', 'font', 'foreground', 1454 'highlightbackground', 'highlightcolor', 'highlightthickness', 1455 'justify', 'padx', 'pady', 'relief', 1456 'takefocus', 'text', 'textvariable', 'width', 1457 ) 1458 _conv_pad_pixels = False 1459 1460 def create(self, **kwargs): 1461 return tkinter.Message(self.root, **kwargs) 1462 1463 def test_configure_aspect(self): 1464 widget = self.create() 1465 self.checkIntegerParam(widget, 'aspect', 250, 0, -300) 1466 1467 1468class DefaultRootTest(AbstractDefaultRootTest, unittest.TestCase): 1469 1470 def test_frame(self): 1471 self._test_widget(tkinter.Frame) 1472 1473 def test_label(self): 1474 self._test_widget(tkinter.Label) 1475 1476 1477tests_gui = ( 1478 ButtonTest, CanvasTest, CheckbuttonTest, EntryTest, 1479 FrameTest, LabelFrameTest,LabelTest, ListboxTest, 1480 MenubuttonTest, MenuTest, MessageTest, OptionMenuTest, 1481 PanedWindowTest, RadiobuttonTest, ScaleTest, ScrollbarTest, 1482 SpinboxTest, TextTest, ToplevelTest, DefaultRootTest, 1483) 1484 1485if __name__ == '__main__': 1486 unittest.main() 1487