ยปCore Development>Code coverage>Lib/tkinter/test/test_ttk/test_widgets.py

Python code coverage for Lib/tkinter/test/test_ttk/test_widgets.py

#countcontent
1n/aimport unittest
2n/aimport tkinter
3n/afrom tkinter import ttk, TclError
4n/afrom test.support import requires
5n/aimport sys
6n/a
7n/afrom tkinter.test.test_ttk.test_functions import MockTclObj
8n/afrom tkinter.test.support import (AbstractTkTest, tcl_version, get_tk_patchlevel,
9n/a simulate_mouse_click)
10n/afrom tkinter.test.widget_tests import (add_standard_options, noconv,
11n/a AbstractWidgetTest, StandardOptionsTests, IntegerSizeTests, PixelSizeTests,
12n/a setUpModule)
13n/a
14n/arequires('gui')
15n/a
16n/a
17n/aclass StandardTtkOptionsTests(StandardOptionsTests):
18n/a
19n/a def test_class(self):
20n/a widget = self.create()
21n/a self.assertEqual(widget['class'], '')
22n/a errmsg='attempt to change read-only option'
23n/a if get_tk_patchlevel() < (8, 6, 0, 'beta', 3):
24n/a errmsg='Attempt to change read-only option'
25n/a self.checkInvalidParam(widget, 'class', 'Foo', errmsg=errmsg)
26n/a widget2 = self.create(class_='Foo')
27n/a self.assertEqual(widget2['class'], 'Foo')
28n/a
29n/a def test_padding(self):
30n/a widget = self.create()
31n/a self.checkParam(widget, 'padding', 0, expected=('0',))
32n/a self.checkParam(widget, 'padding', 5, expected=('5',))
33n/a self.checkParam(widget, 'padding', (5, 6), expected=('5', '6'))
34n/a self.checkParam(widget, 'padding', (5, 6, 7),
35n/a expected=('5', '6', '7'))
36n/a self.checkParam(widget, 'padding', (5, 6, 7, 8),
37n/a expected=('5', '6', '7', '8'))
38n/a self.checkParam(widget, 'padding', ('5p', '6p', '7p', '8p'))
39n/a self.checkParam(widget, 'padding', (), expected='')
40n/a
41n/a def test_style(self):
42n/a widget = self.create()
43n/a self.assertEqual(widget['style'], '')
44n/a errmsg = 'Layout Foo not found'
45n/a if hasattr(self, 'default_orient'):
46n/a errmsg = ('Layout %s.Foo not found' %
47n/a getattr(self, 'default_orient').title())
48n/a self.checkInvalidParam(widget, 'style', 'Foo',
49n/a errmsg=errmsg)
50n/a widget2 = self.create(class_='Foo')
51n/a self.assertEqual(widget2['class'], 'Foo')
52n/a # XXX
53n/a pass
54n/a
55n/a
56n/aclass WidgetTest(AbstractTkTest, unittest.TestCase):
57n/a """Tests methods available in every ttk widget."""
58n/a
59n/a def setUp(self):
60n/a super().setUp()
61n/a self.widget = ttk.Button(self.root, width=0, text="Text")
62n/a self.widget.pack()
63n/a self.widget.wait_visibility()
64n/a
65n/a
66n/a def test_identify(self):
67n/a self.widget.update_idletasks()
68n/a self.assertEqual(self.widget.identify(
69n/a int(self.widget.winfo_width() / 2),
70n/a int(self.widget.winfo_height() / 2)
71n/a ), "label")
72n/a self.assertEqual(self.widget.identify(-1, -1), "")
73n/a
74n/a self.assertRaises(tkinter.TclError, self.widget.identify, None, 5)
75n/a self.assertRaises(tkinter.TclError, self.widget.identify, 5, None)
76n/a self.assertRaises(tkinter.TclError, self.widget.identify, 5, '')
77n/a
78n/a
79n/a def test_widget_state(self):
80n/a # XXX not sure about the portability of all these tests
81n/a self.assertEqual(self.widget.state(), ())
82n/a self.assertEqual(self.widget.instate(['!disabled']), True)
83n/a
84n/a # changing from !disabled to disabled
85n/a self.assertEqual(self.widget.state(['disabled']), ('!disabled', ))
86n/a # no state change
87n/a self.assertEqual(self.widget.state(['disabled']), ())
88n/a # change back to !disable but also active
89n/a self.assertEqual(self.widget.state(['!disabled', 'active']),
90n/a ('!active', 'disabled'))
91n/a # no state changes, again
92n/a self.assertEqual(self.widget.state(['!disabled', 'active']), ())
93n/a self.assertEqual(self.widget.state(['active', '!disabled']), ())
94n/a
95n/a def test_cb(arg1, **kw):
96n/a return arg1, kw
97n/a self.assertEqual(self.widget.instate(['!disabled'],
98n/a test_cb, "hi", **{"msg": "there"}),
99n/a ('hi', {'msg': 'there'}))
100n/a
101n/a # attempt to set invalid statespec
102n/a currstate = self.widget.state()
103n/a self.assertRaises(tkinter.TclError, self.widget.instate,
104n/a ['badstate'])
105n/a self.assertRaises(tkinter.TclError, self.widget.instate,
106n/a ['disabled', 'badstate'])
107n/a # verify that widget didn't change its state
108n/a self.assertEqual(currstate, self.widget.state())
109n/a
110n/a # ensuring that passing None as state doesn't modify current state
111n/a self.widget.state(['active', '!disabled'])
112n/a self.assertEqual(self.widget.state(), ('active', ))
113n/a
114n/a
115n/aclass AbstractToplevelTest(AbstractWidgetTest, PixelSizeTests):
116n/a _conv_pixels = noconv
117n/a
118n/a
119n/a@add_standard_options(StandardTtkOptionsTests)
120n/aclass FrameTest(AbstractToplevelTest, unittest.TestCase):
121n/a OPTIONS = (
122n/a 'borderwidth', 'class', 'cursor', 'height',
123n/a 'padding', 'relief', 'style', 'takefocus',
124n/a 'width',
125n/a )
126n/a
127n/a def create(self, **kwargs):
128n/a return ttk.Frame(self.root, **kwargs)
129n/a
130n/a
131n/a@add_standard_options(StandardTtkOptionsTests)
132n/aclass LabelFrameTest(AbstractToplevelTest, unittest.TestCase):
133n/a OPTIONS = (
134n/a 'borderwidth', 'class', 'cursor', 'height',
135n/a 'labelanchor', 'labelwidget',
136n/a 'padding', 'relief', 'style', 'takefocus',
137n/a 'text', 'underline', 'width',
138n/a )
139n/a
140n/a def create(self, **kwargs):
141n/a return ttk.LabelFrame(self.root, **kwargs)
142n/a
143n/a def test_labelanchor(self):
144n/a widget = self.create()
145n/a self.checkEnumParam(widget, 'labelanchor',
146n/a 'e', 'en', 'es', 'n', 'ne', 'nw', 's', 'se', 'sw', 'w', 'wn', 'ws',
147n/a errmsg='Bad label anchor specification {}')
148n/a self.checkInvalidParam(widget, 'labelanchor', 'center')
149n/a
150n/a def test_labelwidget(self):
151n/a widget = self.create()
152n/a label = ttk.Label(self.root, text='Mupp', name='foo')
153n/a self.checkParam(widget, 'labelwidget', label, expected='.foo')
154n/a label.destroy()
155n/a
156n/a
157n/aclass AbstractLabelTest(AbstractWidgetTest):
158n/a
159n/a def checkImageParam(self, widget, name):
160n/a image = tkinter.PhotoImage(master=self.root, name='image1')
161n/a image2 = tkinter.PhotoImage(master=self.root, name='image2')
162n/a self.checkParam(widget, name, image, expected=('image1',))
163n/a self.checkParam(widget, name, 'image1', expected=('image1',))
164n/a self.checkParam(widget, name, (image,), expected=('image1',))
165n/a self.checkParam(widget, name, (image, 'active', image2),
166n/a expected=('image1', 'active', 'image2'))
167n/a self.checkParam(widget, name, 'image1 active image2',
168n/a expected=('image1', 'active', 'image2'))
169n/a self.checkInvalidParam(widget, name, 'spam',
170n/a errmsg='image "spam" doesn\'t exist')
171n/a
172n/a def test_compound(self):
173n/a widget = self.create()
174n/a self.checkEnumParam(widget, 'compound',
175n/a 'none', 'text', 'image', 'center',
176n/a 'top', 'bottom', 'left', 'right')
177n/a
178n/a def test_state(self):
179n/a widget = self.create()
180n/a self.checkParams(widget, 'state', 'active', 'disabled', 'normal')
181n/a
182n/a def test_width(self):
183n/a widget = self.create()
184n/a self.checkParams(widget, 'width', 402, -402, 0)
185n/a
186n/a
187n/a@add_standard_options(StandardTtkOptionsTests)
188n/aclass LabelTest(AbstractLabelTest, unittest.TestCase):
189n/a OPTIONS = (
190n/a 'anchor', 'background', 'borderwidth',
191n/a 'class', 'compound', 'cursor', 'font', 'foreground',
192n/a 'image', 'justify', 'padding', 'relief', 'state', 'style',
193n/a 'takefocus', 'text', 'textvariable',
194n/a 'underline', 'width', 'wraplength',
195n/a )
196n/a _conv_pixels = noconv
197n/a
198n/a def create(self, **kwargs):
199n/a return ttk.Label(self.root, **kwargs)
200n/a
201n/a def test_font(self):
202n/a widget = self.create()
203n/a self.checkParam(widget, 'font',
204n/a '-Adobe-Helvetica-Medium-R-Normal--*-120-*-*-*-*-*-*')
205n/a
206n/a
207n/a@add_standard_options(StandardTtkOptionsTests)
208n/aclass ButtonTest(AbstractLabelTest, unittest.TestCase):
209n/a OPTIONS = (
210n/a 'class', 'command', 'compound', 'cursor', 'default',
211n/a 'image', 'padding', 'state', 'style',
212n/a 'takefocus', 'text', 'textvariable',
213n/a 'underline', 'width',
214n/a )
215n/a
216n/a def create(self, **kwargs):
217n/a return ttk.Button(self.root, **kwargs)
218n/a
219n/a def test_default(self):
220n/a widget = self.create()
221n/a self.checkEnumParam(widget, 'default', 'normal', 'active', 'disabled')
222n/a
223n/a def test_invoke(self):
224n/a success = []
225n/a btn = ttk.Button(self.root, command=lambda: success.append(1))
226n/a btn.invoke()
227n/a self.assertTrue(success)
228n/a
229n/a
230n/a@add_standard_options(StandardTtkOptionsTests)
231n/aclass CheckbuttonTest(AbstractLabelTest, unittest.TestCase):
232n/a OPTIONS = (
233n/a 'class', 'command', 'compound', 'cursor',
234n/a 'image',
235n/a 'offvalue', 'onvalue',
236n/a 'padding', 'state', 'style',
237n/a 'takefocus', 'text', 'textvariable',
238n/a 'underline', 'variable', 'width',
239n/a )
240n/a
241n/a def create(self, **kwargs):
242n/a return ttk.Checkbutton(self.root, **kwargs)
243n/a
244n/a def test_offvalue(self):
245n/a widget = self.create()
246n/a self.checkParams(widget, 'offvalue', 1, 2.3, '', 'any string')
247n/a
248n/a def test_onvalue(self):
249n/a widget = self.create()
250n/a self.checkParams(widget, 'onvalue', 1, 2.3, '', 'any string')
251n/a
252n/a def test_invoke(self):
253n/a success = []
254n/a def cb_test():
255n/a success.append(1)
256n/a return "cb test called"
257n/a
258n/a cbtn = ttk.Checkbutton(self.root, command=cb_test)
259n/a # the variable automatically created by ttk.Checkbutton is actually
260n/a # undefined till we invoke the Checkbutton
261n/a self.assertEqual(cbtn.state(), ('alternate', ))
262n/a self.assertRaises(tkinter.TclError, cbtn.tk.globalgetvar,
263n/a cbtn['variable'])
264n/a
265n/a res = cbtn.invoke()
266n/a self.assertEqual(res, "cb test called")
267n/a self.assertEqual(cbtn['onvalue'],
268n/a cbtn.tk.globalgetvar(cbtn['variable']))
269n/a self.assertTrue(success)
270n/a
271n/a cbtn['command'] = ''
272n/a res = cbtn.invoke()
273n/a self.assertFalse(str(res))
274n/a self.assertLessEqual(len(success), 1)
275n/a self.assertEqual(cbtn['offvalue'],
276n/a cbtn.tk.globalgetvar(cbtn['variable']))
277n/a
278n/a
279n/a@add_standard_options(IntegerSizeTests, StandardTtkOptionsTests)
280n/aclass EntryTest(AbstractWidgetTest, unittest.TestCase):
281n/a OPTIONS = (
282n/a 'background', 'class', 'cursor',
283n/a 'exportselection', 'font', 'foreground',
284n/a 'invalidcommand', 'justify',
285n/a 'show', 'state', 'style', 'takefocus', 'textvariable',
286n/a 'validate', 'validatecommand', 'width', 'xscrollcommand',
287n/a )
288n/a
289n/a def setUp(self):
290n/a super().setUp()
291n/a self.entry = self.create()
292n/a
293n/a def create(self, **kwargs):
294n/a return ttk.Entry(self.root, **kwargs)
295n/a
296n/a def test_invalidcommand(self):
297n/a widget = self.create()
298n/a self.checkCommandParam(widget, 'invalidcommand')
299n/a
300n/a def test_show(self):
301n/a widget = self.create()
302n/a self.checkParam(widget, 'show', '*')
303n/a self.checkParam(widget, 'show', '')
304n/a self.checkParam(widget, 'show', ' ')
305n/a
306n/a def test_state(self):
307n/a widget = self.create()
308n/a self.checkParams(widget, 'state',
309n/a 'disabled', 'normal', 'readonly')
310n/a
311n/a def test_validate(self):
312n/a widget = self.create()
313n/a self.checkEnumParam(widget, 'validate',
314n/a 'all', 'key', 'focus', 'focusin', 'focusout', 'none')
315n/a
316n/a def test_validatecommand(self):
317n/a widget = self.create()
318n/a self.checkCommandParam(widget, 'validatecommand')
319n/a
320n/a
321n/a def test_bbox(self):
322n/a self.assertIsBoundingBox(self.entry.bbox(0))
323n/a self.assertRaises(tkinter.TclError, self.entry.bbox, 'noindex')
324n/a self.assertRaises(tkinter.TclError, self.entry.bbox, None)
325n/a
326n/a
327n/a def test_identify(self):
328n/a self.entry.pack()
329n/a self.entry.wait_visibility()
330n/a self.entry.update_idletasks()
331n/a
332n/a self.assertEqual(self.entry.identify(5, 5), "textarea")
333n/a self.assertEqual(self.entry.identify(-1, -1), "")
334n/a
335n/a self.assertRaises(tkinter.TclError, self.entry.identify, None, 5)
336n/a self.assertRaises(tkinter.TclError, self.entry.identify, 5, None)
337n/a self.assertRaises(tkinter.TclError, self.entry.identify, 5, '')
338n/a
339n/a
340n/a def test_validation_options(self):
341n/a success = []
342n/a test_invalid = lambda: success.append(True)
343n/a
344n/a self.entry['validate'] = 'none'
345n/a self.entry['validatecommand'] = lambda: False
346n/a
347n/a self.entry['invalidcommand'] = test_invalid
348n/a self.entry.validate()
349n/a self.assertTrue(success)
350n/a
351n/a self.entry['invalidcommand'] = ''
352n/a self.entry.validate()
353n/a self.assertEqual(len(success), 1)
354n/a
355n/a self.entry['invalidcommand'] = test_invalid
356n/a self.entry['validatecommand'] = lambda: True
357n/a self.entry.validate()
358n/a self.assertEqual(len(success), 1)
359n/a
360n/a self.entry['validatecommand'] = ''
361n/a self.entry.validate()
362n/a self.assertEqual(len(success), 1)
363n/a
364n/a self.entry['validatecommand'] = True
365n/a self.assertRaises(tkinter.TclError, self.entry.validate)
366n/a
367n/a
368n/a def test_validation(self):
369n/a validation = []
370n/a def validate(to_insert):
371n/a if not 'a' <= to_insert.lower() <= 'z':
372n/a validation.append(False)
373n/a return False
374n/a validation.append(True)
375n/a return True
376n/a
377n/a self.entry['validate'] = 'key'
378n/a self.entry['validatecommand'] = self.entry.register(validate), '%S'
379n/a
380n/a self.entry.insert('end', 1)
381n/a self.entry.insert('end', 'a')
382n/a self.assertEqual(validation, [False, True])
383n/a self.assertEqual(self.entry.get(), 'a')
384n/a
385n/a
386n/a def test_revalidation(self):
387n/a def validate(content):
388n/a for letter in content:
389n/a if not 'a' <= letter.lower() <= 'z':
390n/a return False
391n/a return True
392n/a
393n/a self.entry['validatecommand'] = self.entry.register(validate), '%P'
394n/a
395n/a self.entry.insert('end', 'avocado')
396n/a self.assertEqual(self.entry.validate(), True)
397n/a self.assertEqual(self.entry.state(), ())
398n/a
399n/a self.entry.delete(0, 'end')
400n/a self.assertEqual(self.entry.get(), '')
401n/a
402n/a self.entry.insert('end', 'a1b')
403n/a self.assertEqual(self.entry.validate(), False)
404n/a self.assertEqual(self.entry.state(), ('invalid', ))
405n/a
406n/a self.entry.delete(1)
407n/a self.assertEqual(self.entry.validate(), True)
408n/a self.assertEqual(self.entry.state(), ())
409n/a
410n/a
411n/a@add_standard_options(IntegerSizeTests, StandardTtkOptionsTests)
412n/aclass ComboboxTest(EntryTest, unittest.TestCase):
413n/a OPTIONS = (
414n/a 'background', 'class', 'cursor', 'exportselection',
415n/a 'font', 'foreground', 'height', 'invalidcommand',
416n/a 'justify', 'postcommand', 'show', 'state', 'style',
417n/a 'takefocus', 'textvariable',
418n/a 'validate', 'validatecommand', 'values',
419n/a 'width', 'xscrollcommand',
420n/a )
421n/a
422n/a def setUp(self):
423n/a super().setUp()
424n/a self.combo = self.create()
425n/a
426n/a def create(self, **kwargs):
427n/a return ttk.Combobox(self.root, **kwargs)
428n/a
429n/a def test_height(self):
430n/a widget = self.create()
431n/a self.checkParams(widget, 'height', 100, 101.2, 102.6, -100, 0, '1i')
432n/a
433n/a def _show_drop_down_listbox(self):
434n/a width = self.combo.winfo_width()
435n/a self.combo.event_generate('<ButtonPress-1>', x=width - 5, y=5)
436n/a self.combo.event_generate('<ButtonRelease-1>', x=width - 5, y=5)
437n/a self.combo.update_idletasks()
438n/a
439n/a
440n/a def test_virtual_event(self):
441n/a success = []
442n/a
443n/a self.combo['values'] = [1]
444n/a self.combo.bind('<<ComboboxSelected>>',
445n/a lambda evt: success.append(True))
446n/a self.combo.pack()
447n/a self.combo.wait_visibility()
448n/a
449n/a height = self.combo.winfo_height()
450n/a self._show_drop_down_listbox()
451n/a self.combo.update()
452n/a self.combo.event_generate('<Return>')
453n/a self.combo.update()
454n/a
455n/a self.assertTrue(success)
456n/a
457n/a
458n/a def test_postcommand(self):
459n/a success = []
460n/a
461n/a self.combo['postcommand'] = lambda: success.append(True)
462n/a self.combo.pack()
463n/a self.combo.wait_visibility()
464n/a
465n/a self._show_drop_down_listbox()
466n/a self.assertTrue(success)
467n/a
468n/a # testing postcommand removal
469n/a self.combo['postcommand'] = ''
470n/a self._show_drop_down_listbox()
471n/a self.assertEqual(len(success), 1)
472n/a
473n/a
474n/a def test_values(self):
475n/a def check_get_current(getval, currval):
476n/a self.assertEqual(self.combo.get(), getval)
477n/a self.assertEqual(self.combo.current(), currval)
478n/a
479n/a self.assertEqual(self.combo['values'],
480n/a () if tcl_version < (8, 5) else '')
481n/a check_get_current('', -1)
482n/a
483n/a self.checkParam(self.combo, 'values', 'mon tue wed thur',
484n/a expected=('mon', 'tue', 'wed', 'thur'))
485n/a self.checkParam(self.combo, 'values', ('mon', 'tue', 'wed', 'thur'))
486n/a self.checkParam(self.combo, 'values', (42, 3.14, '', 'any string'))
487n/a self.checkParam(self.combo, 'values', '',
488n/a expected='' if get_tk_patchlevel() < (8, 5, 10) else ())
489n/a
490n/a self.combo['values'] = ['a', 1, 'c']
491n/a
492n/a self.combo.set('c')
493n/a check_get_current('c', 2)
494n/a
495n/a self.combo.current(0)
496n/a check_get_current('a', 0)
497n/a
498n/a self.combo.set('d')
499n/a check_get_current('d', -1)
500n/a
501n/a # testing values with empty string
502n/a self.combo.set('')
503n/a self.combo['values'] = (1, 2, '', 3)
504n/a check_get_current('', 2)
505n/a
506n/a # testing values with empty string set through configure
507n/a self.combo.configure(values=[1, '', 2])
508n/a self.assertEqual(self.combo['values'],
509n/a ('1', '', '2') if self.wantobjects else
510n/a '1 {} 2')
511n/a
512n/a # testing values with spaces
513n/a self.combo['values'] = ['a b', 'a\tb', 'a\nb']
514n/a self.assertEqual(self.combo['values'],
515n/a ('a b', 'a\tb', 'a\nb') if self.wantobjects else
516n/a '{a b} {a\tb} {a\nb}')
517n/a
518n/a # testing values with special characters
519n/a self.combo['values'] = [r'a\tb', '"a"', '} {']
520n/a self.assertEqual(self.combo['values'],
521n/a (r'a\tb', '"a"', '} {') if self.wantobjects else
522n/a r'a\\tb {"a"} \}\ \{')
523n/a
524n/a # out of range
525n/a self.assertRaises(tkinter.TclError, self.combo.current,
526n/a len(self.combo['values']))
527n/a # it expects an integer (or something that can be converted to int)
528n/a self.assertRaises(tkinter.TclError, self.combo.current, '')
529n/a
530n/a # testing creating combobox with empty string in values
531n/a combo2 = ttk.Combobox(self.root, values=[1, 2, ''])
532n/a self.assertEqual(combo2['values'],
533n/a ('1', '2', '') if self.wantobjects else '1 2 {}')
534n/a combo2.destroy()
535n/a
536n/a
537n/a@add_standard_options(IntegerSizeTests, StandardTtkOptionsTests)
538n/aclass PanedWindowTest(AbstractWidgetTest, unittest.TestCase):
539n/a OPTIONS = (
540n/a 'class', 'cursor', 'height',
541n/a 'orient', 'style', 'takefocus', 'width',
542n/a )
543n/a
544n/a def setUp(self):
545n/a super().setUp()
546n/a self.paned = self.create()
547n/a
548n/a def create(self, **kwargs):
549n/a return ttk.PanedWindow(self.root, **kwargs)
550n/a
551n/a def test_orient(self):
552n/a widget = self.create()
553n/a self.assertEqual(str(widget['orient']), 'vertical')
554n/a errmsg='attempt to change read-only option'
555n/a if get_tk_patchlevel() < (8, 6, 0, 'beta', 3):
556n/a errmsg='Attempt to change read-only option'
557n/a self.checkInvalidParam(widget, 'orient', 'horizontal',
558n/a errmsg=errmsg)
559n/a widget2 = self.create(orient='horizontal')
560n/a self.assertEqual(str(widget2['orient']), 'horizontal')
561n/a
562n/a def test_add(self):
563n/a # attempt to add a child that is not a direct child of the paned window
564n/a label = ttk.Label(self.paned)
565n/a child = ttk.Label(label)
566n/a self.assertRaises(tkinter.TclError, self.paned.add, child)
567n/a label.destroy()
568n/a child.destroy()
569n/a # another attempt
570n/a label = ttk.Label(self.root)
571n/a child = ttk.Label(label)
572n/a self.assertRaises(tkinter.TclError, self.paned.add, child)
573n/a child.destroy()
574n/a label.destroy()
575n/a
576n/a good_child = ttk.Label(self.root)
577n/a self.paned.add(good_child)
578n/a # re-adding a child is not accepted
579n/a self.assertRaises(tkinter.TclError, self.paned.add, good_child)
580n/a
581n/a other_child = ttk.Label(self.paned)
582n/a self.paned.add(other_child)
583n/a self.assertEqual(self.paned.pane(0), self.paned.pane(1))
584n/a self.assertRaises(tkinter.TclError, self.paned.pane, 2)
585n/a good_child.destroy()
586n/a other_child.destroy()
587n/a self.assertRaises(tkinter.TclError, self.paned.pane, 0)
588n/a
589n/a
590n/a def test_forget(self):
591n/a self.assertRaises(tkinter.TclError, self.paned.forget, None)
592n/a self.assertRaises(tkinter.TclError, self.paned.forget, 0)
593n/a
594n/a self.paned.add(ttk.Label(self.root))
595n/a self.paned.forget(0)
596n/a self.assertRaises(tkinter.TclError, self.paned.forget, 0)
597n/a
598n/a
599n/a def test_insert(self):
600n/a self.assertRaises(tkinter.TclError, self.paned.insert, None, 0)
601n/a self.assertRaises(tkinter.TclError, self.paned.insert, 0, None)
602n/a self.assertRaises(tkinter.TclError, self.paned.insert, 0, 0)
603n/a
604n/a child = ttk.Label(self.root)
605n/a child2 = ttk.Label(self.root)
606n/a child3 = ttk.Label(self.root)
607n/a
608n/a self.assertRaises(tkinter.TclError, self.paned.insert, 0, child)
609n/a
610n/a self.paned.insert('end', child2)
611n/a self.paned.insert(0, child)
612n/a self.assertEqual(self.paned.panes(), (str(child), str(child2)))
613n/a
614n/a self.paned.insert(0, child2)
615n/a self.assertEqual(self.paned.panes(), (str(child2), str(child)))
616n/a
617n/a self.paned.insert('end', child3)
618n/a self.assertEqual(self.paned.panes(),
619n/a (str(child2), str(child), str(child3)))
620n/a
621n/a # reinserting a child should move it to its current position
622n/a panes = self.paned.panes()
623n/a self.paned.insert('end', child3)
624n/a self.assertEqual(panes, self.paned.panes())
625n/a
626n/a # moving child3 to child2 position should result in child2 ending up
627n/a # in previous child position and child ending up in previous child3
628n/a # position
629n/a self.paned.insert(child2, child3)
630n/a self.assertEqual(self.paned.panes(),
631n/a (str(child3), str(child2), str(child)))
632n/a
633n/a
634n/a def test_pane(self):
635n/a self.assertRaises(tkinter.TclError, self.paned.pane, 0)
636n/a
637n/a child = ttk.Label(self.root)
638n/a self.paned.add(child)
639n/a self.assertIsInstance(self.paned.pane(0), dict)
640n/a self.assertEqual(self.paned.pane(0, weight=None),
641n/a 0 if self.wantobjects else '0')
642n/a # newer form for querying a single option
643n/a self.assertEqual(self.paned.pane(0, 'weight'),
644n/a 0 if self.wantobjects else '0')
645n/a self.assertEqual(self.paned.pane(0), self.paned.pane(str(child)))
646n/a
647n/a self.assertRaises(tkinter.TclError, self.paned.pane, 0,
648n/a badoption='somevalue')
649n/a
650n/a
651n/a def test_sashpos(self):
652n/a self.assertRaises(tkinter.TclError, self.paned.sashpos, None)
653n/a self.assertRaises(tkinter.TclError, self.paned.sashpos, '')
654n/a self.assertRaises(tkinter.TclError, self.paned.sashpos, 0)
655n/a
656n/a child = ttk.Label(self.paned, text='a')
657n/a self.paned.add(child, weight=1)
658n/a self.assertRaises(tkinter.TclError, self.paned.sashpos, 0)
659n/a child2 = ttk.Label(self.paned, text='b')
660n/a self.paned.add(child2)
661n/a self.assertRaises(tkinter.TclError, self.paned.sashpos, 1)
662n/a
663n/a self.paned.pack(expand=True, fill='both')
664n/a self.paned.wait_visibility()
665n/a
666n/a curr_pos = self.paned.sashpos(0)
667n/a self.paned.sashpos(0, 1000)
668n/a self.assertNotEqual(curr_pos, self.paned.sashpos(0))
669n/a self.assertIsInstance(self.paned.sashpos(0), int)
670n/a
671n/a
672n/a@add_standard_options(StandardTtkOptionsTests)
673n/aclass RadiobuttonTest(AbstractLabelTest, unittest.TestCase):
674n/a OPTIONS = (
675n/a 'class', 'command', 'compound', 'cursor',
676n/a 'image',
677n/a 'padding', 'state', 'style',
678n/a 'takefocus', 'text', 'textvariable',
679n/a 'underline', 'value', 'variable', 'width',
680n/a )
681n/a
682n/a def create(self, **kwargs):
683n/a return ttk.Radiobutton(self.root, **kwargs)
684n/a
685n/a def test_value(self):
686n/a widget = self.create()
687n/a self.checkParams(widget, 'value', 1, 2.3, '', 'any string')
688n/a
689n/a def test_invoke(self):
690n/a success = []
691n/a def cb_test():
692n/a success.append(1)
693n/a return "cb test called"
694n/a
695n/a myvar = tkinter.IntVar(self.root)
696n/a cbtn = ttk.Radiobutton(self.root, command=cb_test,
697n/a variable=myvar, value=0)
698n/a cbtn2 = ttk.Radiobutton(self.root, command=cb_test,
699n/a variable=myvar, value=1)
700n/a
701n/a if self.wantobjects:
702n/a conv = lambda x: x
703n/a else:
704n/a conv = int
705n/a
706n/a res = cbtn.invoke()
707n/a self.assertEqual(res, "cb test called")
708n/a self.assertEqual(conv(cbtn['value']), myvar.get())
709n/a self.assertEqual(myvar.get(),
710n/a conv(cbtn.tk.globalgetvar(cbtn['variable'])))
711n/a self.assertTrue(success)
712n/a
713n/a cbtn2['command'] = ''
714n/a res = cbtn2.invoke()
715n/a self.assertEqual(str(res), '')
716n/a self.assertLessEqual(len(success), 1)
717n/a self.assertEqual(conv(cbtn2['value']), myvar.get())
718n/a self.assertEqual(myvar.get(),
719n/a conv(cbtn.tk.globalgetvar(cbtn['variable'])))
720n/a
721n/a self.assertEqual(str(cbtn['variable']), str(cbtn2['variable']))
722n/a
723n/a
724n/aclass MenubuttonTest(AbstractLabelTest, unittest.TestCase):
725n/a OPTIONS = (
726n/a 'class', 'compound', 'cursor', 'direction',
727n/a 'image', 'menu', 'padding', 'state', 'style',
728n/a 'takefocus', 'text', 'textvariable',
729n/a 'underline', 'width',
730n/a )
731n/a
732n/a def create(self, **kwargs):
733n/a return ttk.Menubutton(self.root, **kwargs)
734n/a
735n/a def test_direction(self):
736n/a widget = self.create()
737n/a self.checkEnumParam(widget, 'direction',
738n/a 'above', 'below', 'left', 'right', 'flush')
739n/a
740n/a def test_menu(self):
741n/a widget = self.create()
742n/a menu = tkinter.Menu(widget, name='menu')
743n/a self.checkParam(widget, 'menu', menu, conv=str)
744n/a menu.destroy()
745n/a
746n/a
747n/a@add_standard_options(StandardTtkOptionsTests)
748n/aclass ScaleTest(AbstractWidgetTest, unittest.TestCase):
749n/a OPTIONS = (
750n/a 'class', 'command', 'cursor', 'from', 'length',
751n/a 'orient', 'style', 'takefocus', 'to', 'value', 'variable',
752n/a )
753n/a _conv_pixels = noconv
754n/a default_orient = 'horizontal'
755n/a
756n/a def setUp(self):
757n/a super().setUp()
758n/a self.scale = self.create()
759n/a self.scale.pack()
760n/a self.scale.update()
761n/a
762n/a def create(self, **kwargs):
763n/a return ttk.Scale(self.root, **kwargs)
764n/a
765n/a def test_from(self):
766n/a widget = self.create()
767n/a self.checkFloatParam(widget, 'from', 100, 14.9, 15.1, conv=False)
768n/a
769n/a def test_length(self):
770n/a widget = self.create()
771n/a self.checkPixelsParam(widget, 'length', 130, 131.2, 135.6, '5i')
772n/a
773n/a def test_to(self):
774n/a widget = self.create()
775n/a self.checkFloatParam(widget, 'to', 300, 14.9, 15.1, -10, conv=False)
776n/a
777n/a def test_value(self):
778n/a widget = self.create()
779n/a self.checkFloatParam(widget, 'value', 300, 14.9, 15.1, -10, conv=False)
780n/a
781n/a def test_custom_event(self):
782n/a failure = [1, 1, 1] # will need to be empty
783n/a
784n/a funcid = self.scale.bind('<<RangeChanged>>', lambda evt: failure.pop())
785n/a
786n/a self.scale['from'] = 10
787n/a self.scale['from_'] = 10
788n/a self.scale['to'] = 3
789n/a
790n/a self.assertFalse(failure)
791n/a
792n/a failure = [1, 1, 1]
793n/a self.scale.configure(from_=2, to=5)
794n/a self.scale.configure(from_=0, to=-2)
795n/a self.scale.configure(to=10)
796n/a
797n/a self.assertFalse(failure)
798n/a
799n/a
800n/a def test_get(self):
801n/a if self.wantobjects:
802n/a conv = lambda x: x
803n/a else:
804n/a conv = float
805n/a
806n/a scale_width = self.scale.winfo_width()
807n/a self.assertEqual(self.scale.get(scale_width, 0), self.scale['to'])
808n/a
809n/a self.assertEqual(conv(self.scale.get(0, 0)), conv(self.scale['from']))
810n/a self.assertEqual(self.scale.get(), self.scale['value'])
811n/a self.scale['value'] = 30
812n/a self.assertEqual(self.scale.get(), self.scale['value'])
813n/a
814n/a self.assertRaises(tkinter.TclError, self.scale.get, '', 0)
815n/a self.assertRaises(tkinter.TclError, self.scale.get, 0, '')
816n/a
817n/a
818n/a def test_set(self):
819n/a if self.wantobjects:
820n/a conv = lambda x: x
821n/a else:
822n/a conv = float
823n/a
824n/a # set restricts the max/min values according to the current range
825n/a max = conv(self.scale['to'])
826n/a new_max = max + 10
827n/a self.scale.set(new_max)
828n/a self.assertEqual(conv(self.scale.get()), max)
829n/a min = conv(self.scale['from'])
830n/a self.scale.set(min - 1)
831n/a self.assertEqual(conv(self.scale.get()), min)
832n/a
833n/a # changing directly the variable doesn't impose this limitation tho
834n/a var = tkinter.DoubleVar(self.root)
835n/a self.scale['variable'] = var
836n/a var.set(max + 5)
837n/a self.assertEqual(conv(self.scale.get()), var.get())
838n/a self.assertEqual(conv(self.scale.get()), max + 5)
839n/a del var
840n/a
841n/a # the same happens with the value option
842n/a self.scale['value'] = max + 10
843n/a self.assertEqual(conv(self.scale.get()), max + 10)
844n/a self.assertEqual(conv(self.scale.get()), conv(self.scale['value']))
845n/a
846n/a # nevertheless, note that the max/min values we can get specifying
847n/a # x, y coords are the ones according to the current range
848n/a self.assertEqual(conv(self.scale.get(0, 0)), min)
849n/a self.assertEqual(conv(self.scale.get(self.scale.winfo_width(), 0)), max)
850n/a
851n/a self.assertRaises(tkinter.TclError, self.scale.set, None)
852n/a
853n/a
854n/a@add_standard_options(StandardTtkOptionsTests)
855n/aclass ProgressbarTest(AbstractWidgetTest, unittest.TestCase):
856n/a OPTIONS = (
857n/a 'class', 'cursor', 'orient', 'length',
858n/a 'mode', 'maximum', 'phase',
859n/a 'style', 'takefocus', 'value', 'variable',
860n/a )
861n/a _conv_pixels = noconv
862n/a default_orient = 'horizontal'
863n/a
864n/a def create(self, **kwargs):
865n/a return ttk.Progressbar(self.root, **kwargs)
866n/a
867n/a def test_length(self):
868n/a widget = self.create()
869n/a self.checkPixelsParam(widget, 'length', 100.1, 56.7, '2i')
870n/a
871n/a def test_maximum(self):
872n/a widget = self.create()
873n/a self.checkFloatParam(widget, 'maximum', 150.2, 77.7, 0, -10, conv=False)
874n/a
875n/a def test_mode(self):
876n/a widget = self.create()
877n/a self.checkEnumParam(widget, 'mode', 'determinate', 'indeterminate')
878n/a
879n/a def test_phase(self):
880n/a # XXX
881n/a pass
882n/a
883n/a def test_value(self):
884n/a widget = self.create()
885n/a self.checkFloatParam(widget, 'value', 150.2, 77.7, 0, -10,
886n/a conv=False)
887n/a
888n/a
889n/a@unittest.skipIf(sys.platform == 'darwin',
890n/a 'ttk.Scrollbar is special on MacOSX')
891n/a@add_standard_options(StandardTtkOptionsTests)
892n/aclass ScrollbarTest(AbstractWidgetTest, unittest.TestCase):
893n/a OPTIONS = (
894n/a 'class', 'command', 'cursor', 'orient', 'style', 'takefocus',
895n/a )
896n/a default_orient = 'vertical'
897n/a
898n/a def create(self, **kwargs):
899n/a return ttk.Scrollbar(self.root, **kwargs)
900n/a
901n/a
902n/a@add_standard_options(IntegerSizeTests, StandardTtkOptionsTests)
903n/aclass NotebookTest(AbstractWidgetTest, unittest.TestCase):
904n/a OPTIONS = (
905n/a 'class', 'cursor', 'height', 'padding', 'style', 'takefocus', 'width',
906n/a )
907n/a
908n/a def setUp(self):
909n/a super().setUp()
910n/a self.nb = self.create(padding=0)
911n/a self.child1 = ttk.Label(self.root)
912n/a self.child2 = ttk.Label(self.root)
913n/a self.nb.add(self.child1, text='a')
914n/a self.nb.add(self.child2, text='b')
915n/a
916n/a def create(self, **kwargs):
917n/a return ttk.Notebook(self.root, **kwargs)
918n/a
919n/a def test_tab_identifiers(self):
920n/a self.nb.forget(0)
921n/a self.nb.hide(self.child2)
922n/a self.assertRaises(tkinter.TclError, self.nb.tab, self.child1)
923n/a self.assertEqual(self.nb.index('end'), 1)
924n/a self.nb.add(self.child2)
925n/a self.assertEqual(self.nb.index('end'), 1)
926n/a self.nb.select(self.child2)
927n/a
928n/a self.assertTrue(self.nb.tab('current'))
929n/a self.nb.add(self.child1, text='a')
930n/a
931n/a self.nb.pack()
932n/a self.nb.wait_visibility()
933n/a if sys.platform == 'darwin':
934n/a tb_idx = "@20,5"
935n/a else:
936n/a tb_idx = "@5,5"
937n/a self.assertEqual(self.nb.tab(tb_idx), self.nb.tab('current'))
938n/a
939n/a for i in range(5, 100, 5):
940n/a try:
941n/a if self.nb.tab('@%d, 5' % i, text=None) == 'a':
942n/a break
943n/a except tkinter.TclError:
944n/a pass
945n/a
946n/a else:
947n/a self.fail("Tab with text 'a' not found")
948n/a
949n/a
950n/a def test_add_and_hidden(self):
951n/a self.assertRaises(tkinter.TclError, self.nb.hide, -1)
952n/a self.assertRaises(tkinter.TclError, self.nb.hide, 'hi')
953n/a self.assertRaises(tkinter.TclError, self.nb.hide, None)
954n/a self.assertRaises(tkinter.TclError, self.nb.add, None)
955n/a self.assertRaises(tkinter.TclError, self.nb.add, ttk.Label(self.root),
956n/a unknown='option')
957n/a
958n/a tabs = self.nb.tabs()
959n/a self.nb.hide(self.child1)
960n/a self.nb.add(self.child1)
961n/a self.assertEqual(self.nb.tabs(), tabs)
962n/a
963n/a child = ttk.Label(self.root)
964n/a self.nb.add(child, text='c')
965n/a tabs = self.nb.tabs()
966n/a
967n/a curr = self.nb.index('current')
968n/a # verify that the tab gets readded at its previous position
969n/a child2_index = self.nb.index(self.child2)
970n/a self.nb.hide(self.child2)
971n/a self.nb.add(self.child2)
972n/a self.assertEqual(self.nb.tabs(), tabs)
973n/a self.assertEqual(self.nb.index(self.child2), child2_index)
974n/a self.assertEqual(str(self.child2), self.nb.tabs()[child2_index])
975n/a # but the tab next to it (not hidden) is the one selected now
976n/a self.assertEqual(self.nb.index('current'), curr + 1)
977n/a
978n/a
979n/a def test_forget(self):
980n/a self.assertRaises(tkinter.TclError, self.nb.forget, -1)
981n/a self.assertRaises(tkinter.TclError, self.nb.forget, 'hi')
982n/a self.assertRaises(tkinter.TclError, self.nb.forget, None)
983n/a
984n/a tabs = self.nb.tabs()
985n/a child1_index = self.nb.index(self.child1)
986n/a self.nb.forget(self.child1)
987n/a self.assertNotIn(str(self.child1), self.nb.tabs())
988n/a self.assertEqual(len(tabs) - 1, len(self.nb.tabs()))
989n/a
990n/a self.nb.add(self.child1)
991n/a self.assertEqual(self.nb.index(self.child1), 1)
992n/a self.assertNotEqual(child1_index, self.nb.index(self.child1))
993n/a
994n/a
995n/a def test_index(self):
996n/a self.assertRaises(tkinter.TclError, self.nb.index, -1)
997n/a self.assertRaises(tkinter.TclError, self.nb.index, None)
998n/a
999n/a self.assertIsInstance(self.nb.index('end'), int)
1000n/a self.assertEqual(self.nb.index(self.child1), 0)
1001n/a self.assertEqual(self.nb.index(self.child2), 1)
1002n/a self.assertEqual(self.nb.index('end'), 2)
1003n/a
1004n/a
1005n/a def test_insert(self):
1006n/a # moving tabs
1007n/a tabs = self.nb.tabs()
1008n/a self.nb.insert(1, tabs[0])
1009n/a self.assertEqual(self.nb.tabs(), (tabs[1], tabs[0]))
1010n/a self.nb.insert(self.child1, self.child2)
1011n/a self.assertEqual(self.nb.tabs(), tabs)
1012n/a self.nb.insert('end', self.child1)
1013n/a self.assertEqual(self.nb.tabs(), (tabs[1], tabs[0]))
1014n/a self.nb.insert('end', 0)
1015n/a self.assertEqual(self.nb.tabs(), tabs)
1016n/a # bad moves
1017n/a self.assertRaises(tkinter.TclError, self.nb.insert, 2, tabs[0])
1018n/a self.assertRaises(tkinter.TclError, self.nb.insert, -1, tabs[0])
1019n/a
1020n/a # new tab
1021n/a child3 = ttk.Label(self.root)
1022n/a self.nb.insert(1, child3)
1023n/a self.assertEqual(self.nb.tabs(), (tabs[0], str(child3), tabs[1]))
1024n/a self.nb.forget(child3)
1025n/a self.assertEqual(self.nb.tabs(), tabs)
1026n/a self.nb.insert(self.child1, child3)
1027n/a self.assertEqual(self.nb.tabs(), (str(child3), ) + tabs)
1028n/a self.nb.forget(child3)
1029n/a self.assertRaises(tkinter.TclError, self.nb.insert, 2, child3)
1030n/a self.assertRaises(tkinter.TclError, self.nb.insert, -1, child3)
1031n/a
1032n/a # bad inserts
1033n/a self.assertRaises(tkinter.TclError, self.nb.insert, 'end', None)
1034n/a self.assertRaises(tkinter.TclError, self.nb.insert, None, 0)
1035n/a self.assertRaises(tkinter.TclError, self.nb.insert, None, None)
1036n/a
1037n/a
1038n/a def test_select(self):
1039n/a self.nb.pack()
1040n/a self.nb.wait_visibility()
1041n/a
1042n/a success = []
1043n/a tab_changed = []
1044n/a
1045n/a self.child1.bind('<Unmap>', lambda evt: success.append(True))
1046n/a self.nb.bind('<<NotebookTabChanged>>',
1047n/a lambda evt: tab_changed.append(True))
1048n/a
1049n/a self.assertEqual(self.nb.select(), str(self.child1))
1050n/a self.nb.select(self.child2)
1051n/a self.assertTrue(success)
1052n/a self.assertEqual(self.nb.select(), str(self.child2))
1053n/a
1054n/a self.nb.update()
1055n/a self.assertTrue(tab_changed)
1056n/a
1057n/a
1058n/a def test_tab(self):
1059n/a self.assertRaises(tkinter.TclError, self.nb.tab, -1)
1060n/a self.assertRaises(tkinter.TclError, self.nb.tab, 'notab')
1061n/a self.assertRaises(tkinter.TclError, self.nb.tab, None)
1062n/a
1063n/a self.assertIsInstance(self.nb.tab(self.child1), dict)
1064n/a self.assertEqual(self.nb.tab(self.child1, text=None), 'a')
1065n/a # newer form for querying a single option
1066n/a self.assertEqual(self.nb.tab(self.child1, 'text'), 'a')
1067n/a self.nb.tab(self.child1, text='abc')
1068n/a self.assertEqual(self.nb.tab(self.child1, text=None), 'abc')
1069n/a self.assertEqual(self.nb.tab(self.child1, 'text'), 'abc')
1070n/a
1071n/a
1072n/a def test_tabs(self):
1073n/a self.assertEqual(len(self.nb.tabs()), 2)
1074n/a
1075n/a self.nb.forget(self.child1)
1076n/a self.nb.forget(self.child2)
1077n/a
1078n/a self.assertEqual(self.nb.tabs(), ())
1079n/a
1080n/a
1081n/a def test_traversal(self):
1082n/a self.nb.pack()
1083n/a self.nb.wait_visibility()
1084n/a
1085n/a self.nb.select(0)
1086n/a
1087n/a simulate_mouse_click(self.nb, 5, 5)
1088n/a self.nb.focus_force()
1089n/a self.nb.event_generate('<Control-Tab>')
1090n/a self.assertEqual(self.nb.select(), str(self.child2))
1091n/a self.nb.focus_force()
1092n/a self.nb.event_generate('<Shift-Control-Tab>')
1093n/a self.assertEqual(self.nb.select(), str(self.child1))
1094n/a self.nb.focus_force()
1095n/a self.nb.event_generate('<Shift-Control-Tab>')
1096n/a self.assertEqual(self.nb.select(), str(self.child2))
1097n/a
1098n/a self.nb.tab(self.child1, text='a', underline=0)
1099n/a self.nb.enable_traversal()
1100n/a self.nb.focus_force()
1101n/a simulate_mouse_click(self.nb, 5, 5)
1102n/a if sys.platform == 'darwin':
1103n/a self.nb.event_generate('<Option-a>')
1104n/a else:
1105n/a self.nb.event_generate('<Alt-a>')
1106n/a self.assertEqual(self.nb.select(), str(self.child1))
1107n/a
1108n/a
1109n/a@add_standard_options(StandardTtkOptionsTests)
1110n/aclass TreeviewTest(AbstractWidgetTest, unittest.TestCase):
1111n/a OPTIONS = (
1112n/a 'class', 'columns', 'cursor', 'displaycolumns',
1113n/a 'height', 'padding', 'selectmode', 'show',
1114n/a 'style', 'takefocus', 'xscrollcommand', 'yscrollcommand',
1115n/a )
1116n/a
1117n/a def setUp(self):
1118n/a super().setUp()
1119n/a self.tv = self.create(padding=0)
1120n/a
1121n/a def create(self, **kwargs):
1122n/a return ttk.Treeview(self.root, **kwargs)
1123n/a
1124n/a def test_columns(self):
1125n/a widget = self.create()
1126n/a self.checkParam(widget, 'columns', 'a b c',
1127n/a expected=('a', 'b', 'c'))
1128n/a self.checkParam(widget, 'columns', ('a', 'b', 'c'))
1129n/a self.checkParam(widget, 'columns', (),
1130n/a expected='' if get_tk_patchlevel() < (8, 5, 10) else ())
1131n/a
1132n/a def test_displaycolumns(self):
1133n/a widget = self.create()
1134n/a widget['columns'] = ('a', 'b', 'c')
1135n/a self.checkParam(widget, 'displaycolumns', 'b a c',
1136n/a expected=('b', 'a', 'c'))
1137n/a self.checkParam(widget, 'displaycolumns', ('b', 'a', 'c'))
1138n/a self.checkParam(widget, 'displaycolumns', '#all',
1139n/a expected=('#all',))
1140n/a self.checkParam(widget, 'displaycolumns', (2, 1, 0))
1141n/a self.checkInvalidParam(widget, 'displaycolumns', ('a', 'b', 'd'),
1142n/a errmsg='Invalid column index d')
1143n/a self.checkInvalidParam(widget, 'displaycolumns', (1, 2, 3),
1144n/a errmsg='Column index 3 out of bounds')
1145n/a self.checkInvalidParam(widget, 'displaycolumns', (1, -2),
1146n/a errmsg='Column index -2 out of bounds')
1147n/a
1148n/a def test_height(self):
1149n/a widget = self.create()
1150n/a self.checkPixelsParam(widget, 'height', 100, -100, 0, '3c', conv=False)
1151n/a self.checkPixelsParam(widget, 'height', 101.2, 102.6, conv=noconv)
1152n/a
1153n/a def test_selectmode(self):
1154n/a widget = self.create()
1155n/a self.checkEnumParam(widget, 'selectmode',
1156n/a 'none', 'browse', 'extended')
1157n/a
1158n/a def test_show(self):
1159n/a widget = self.create()
1160n/a self.checkParam(widget, 'show', 'tree headings',
1161n/a expected=('tree', 'headings'))
1162n/a self.checkParam(widget, 'show', ('tree', 'headings'))
1163n/a self.checkParam(widget, 'show', ('headings', 'tree'))
1164n/a self.checkParam(widget, 'show', 'tree', expected=('tree',))
1165n/a self.checkParam(widget, 'show', 'headings', expected=('headings',))
1166n/a
1167n/a def test_bbox(self):
1168n/a self.tv.pack()
1169n/a self.assertEqual(self.tv.bbox(''), '')
1170n/a self.tv.wait_visibility()
1171n/a self.tv.update()
1172n/a
1173n/a item_id = self.tv.insert('', 'end')
1174n/a children = self.tv.get_children()
1175n/a self.assertTrue(children)
1176n/a
1177n/a bbox = self.tv.bbox(children[0])
1178n/a self.assertIsBoundingBox(bbox)
1179n/a
1180n/a # compare width in bboxes
1181n/a self.tv['columns'] = ['test']
1182n/a self.tv.column('test', width=50)
1183n/a bbox_column0 = self.tv.bbox(children[0], 0)
1184n/a root_width = self.tv.column('#0', width=None)
1185n/a if not self.wantobjects:
1186n/a root_width = int(root_width)
1187n/a self.assertEqual(bbox_column0[0], bbox[0] + root_width)
1188n/a
1189n/a # verify that bbox of a closed item is the empty string
1190n/a child1 = self.tv.insert(item_id, 'end')
1191n/a self.assertEqual(self.tv.bbox(child1), '')
1192n/a
1193n/a
1194n/a def test_children(self):
1195n/a # no children yet, should get an empty tuple
1196n/a self.assertEqual(self.tv.get_children(), ())
1197n/a
1198n/a item_id = self.tv.insert('', 'end')
1199n/a self.assertIsInstance(self.tv.get_children(), tuple)
1200n/a self.assertEqual(self.tv.get_children()[0], item_id)
1201n/a
1202n/a # add item_id and child3 as children of child2
1203n/a child2 = self.tv.insert('', 'end')
1204n/a child3 = self.tv.insert('', 'end')
1205n/a self.tv.set_children(child2, item_id, child3)
1206n/a self.assertEqual(self.tv.get_children(child2), (item_id, child3))
1207n/a
1208n/a # child3 has child2 as parent, thus trying to set child2 as a children
1209n/a # of child3 should result in an error
1210n/a self.assertRaises(tkinter.TclError,
1211n/a self.tv.set_children, child3, child2)
1212n/a
1213n/a # remove child2 children
1214n/a self.tv.set_children(child2)
1215n/a self.assertEqual(self.tv.get_children(child2), ())
1216n/a
1217n/a # remove root's children
1218n/a self.tv.set_children('')
1219n/a self.assertEqual(self.tv.get_children(), ())
1220n/a
1221n/a
1222n/a def test_column(self):
1223n/a # return a dict with all options/values
1224n/a self.assertIsInstance(self.tv.column('#0'), dict)
1225n/a # return a single value of the given option
1226n/a if self.wantobjects:
1227n/a self.assertIsInstance(self.tv.column('#0', width=None), int)
1228n/a # set a new value for an option
1229n/a self.tv.column('#0', width=10)
1230n/a # testing new way to get option value
1231n/a self.assertEqual(self.tv.column('#0', 'width'),
1232n/a 10 if self.wantobjects else '10')
1233n/a self.assertEqual(self.tv.column('#0', width=None),
1234n/a 10 if self.wantobjects else '10')
1235n/a # check read-only option
1236n/a self.assertRaises(tkinter.TclError, self.tv.column, '#0', id='X')
1237n/a
1238n/a self.assertRaises(tkinter.TclError, self.tv.column, 'invalid')
1239n/a invalid_kws = [
1240n/a {'unknown_option': 'some value'}, {'stretch': 'wrong'},
1241n/a {'anchor': 'wrong'}, {'width': 'wrong'}, {'minwidth': 'wrong'}
1242n/a ]
1243n/a for kw in invalid_kws:
1244n/a self.assertRaises(tkinter.TclError, self.tv.column, '#0',
1245n/a **kw)
1246n/a
1247n/a
1248n/a def test_delete(self):
1249n/a self.assertRaises(tkinter.TclError, self.tv.delete, '#0')
1250n/a
1251n/a item_id = self.tv.insert('', 'end')
1252n/a item2 = self.tv.insert(item_id, 'end')
1253n/a self.assertEqual(self.tv.get_children(), (item_id, ))
1254n/a self.assertEqual(self.tv.get_children(item_id), (item2, ))
1255n/a
1256n/a self.tv.delete(item_id)
1257n/a self.assertFalse(self.tv.get_children())
1258n/a
1259n/a # reattach should fail
1260n/a self.assertRaises(tkinter.TclError,
1261n/a self.tv.reattach, item_id, '', 'end')
1262n/a
1263n/a # test multiple item delete
1264n/a item1 = self.tv.insert('', 'end')
1265n/a item2 = self.tv.insert('', 'end')
1266n/a self.assertEqual(self.tv.get_children(), (item1, item2))
1267n/a
1268n/a self.tv.delete(item1, item2)
1269n/a self.assertFalse(self.tv.get_children())
1270n/a
1271n/a
1272n/a def test_detach_reattach(self):
1273n/a item_id = self.tv.insert('', 'end')
1274n/a item2 = self.tv.insert(item_id, 'end')
1275n/a
1276n/a # calling detach without items is valid, although it does nothing
1277n/a prev = self.tv.get_children()
1278n/a self.tv.detach() # this should do nothing
1279n/a self.assertEqual(prev, self.tv.get_children())
1280n/a
1281n/a self.assertEqual(self.tv.get_children(), (item_id, ))
1282n/a self.assertEqual(self.tv.get_children(item_id), (item2, ))
1283n/a
1284n/a # detach item with children
1285n/a self.tv.detach(item_id)
1286n/a self.assertFalse(self.tv.get_children())
1287n/a
1288n/a # reattach item with children
1289n/a self.tv.reattach(item_id, '', 'end')
1290n/a self.assertEqual(self.tv.get_children(), (item_id, ))
1291n/a self.assertEqual(self.tv.get_children(item_id), (item2, ))
1292n/a
1293n/a # move a children to the root
1294n/a self.tv.move(item2, '', 'end')
1295n/a self.assertEqual(self.tv.get_children(), (item_id, item2))
1296n/a self.assertEqual(self.tv.get_children(item_id), ())
1297n/a
1298n/a # bad values
1299n/a self.assertRaises(tkinter.TclError,
1300n/a self.tv.reattach, 'nonexistent', '', 'end')
1301n/a self.assertRaises(tkinter.TclError,
1302n/a self.tv.detach, 'nonexistent')
1303n/a self.assertRaises(tkinter.TclError,
1304n/a self.tv.reattach, item2, 'otherparent', 'end')
1305n/a self.assertRaises(tkinter.TclError,
1306n/a self.tv.reattach, item2, '', 'invalid')
1307n/a
1308n/a # multiple detach
1309n/a self.tv.detach(item_id, item2)
1310n/a self.assertEqual(self.tv.get_children(), ())
1311n/a self.assertEqual(self.tv.get_children(item_id), ())
1312n/a
1313n/a
1314n/a def test_exists(self):
1315n/a self.assertEqual(self.tv.exists('something'), False)
1316n/a self.assertEqual(self.tv.exists(''), True)
1317n/a self.assertEqual(self.tv.exists({}), False)
1318n/a
1319n/a # the following will make a tk.call equivalent to
1320n/a # tk.call(treeview, "exists") which should result in an error
1321n/a # in the tcl interpreter since tk requires an item.
1322n/a self.assertRaises(tkinter.TclError, self.tv.exists, None)
1323n/a
1324n/a
1325n/a def test_focus(self):
1326n/a # nothing is focused right now
1327n/a self.assertEqual(self.tv.focus(), '')
1328n/a
1329n/a item1 = self.tv.insert('', 'end')
1330n/a self.tv.focus(item1)
1331n/a self.assertEqual(self.tv.focus(), item1)
1332n/a
1333n/a self.tv.delete(item1)
1334n/a self.assertEqual(self.tv.focus(), '')
1335n/a
1336n/a # try focusing inexistent item
1337n/a self.assertRaises(tkinter.TclError, self.tv.focus, 'hi')
1338n/a
1339n/a
1340n/a def test_heading(self):
1341n/a # check a dict is returned
1342n/a self.assertIsInstance(self.tv.heading('#0'), dict)
1343n/a
1344n/a # check a value is returned
1345n/a self.tv.heading('#0', text='hi')
1346n/a self.assertEqual(self.tv.heading('#0', 'text'), 'hi')
1347n/a self.assertEqual(self.tv.heading('#0', text=None), 'hi')
1348n/a
1349n/a # invalid option
1350n/a self.assertRaises(tkinter.TclError, self.tv.heading, '#0',
1351n/a background=None)
1352n/a # invalid value
1353n/a self.assertRaises(tkinter.TclError, self.tv.heading, '#0',
1354n/a anchor=1)
1355n/a
1356n/a def test_heading_callback(self):
1357n/a def simulate_heading_click(x, y):
1358n/a simulate_mouse_click(self.tv, x, y)
1359n/a self.tv.update()
1360n/a
1361n/a success = [] # no success for now
1362n/a
1363n/a self.tv.pack()
1364n/a self.tv.wait_visibility()
1365n/a self.tv.heading('#0', command=lambda: success.append(True))
1366n/a self.tv.column('#0', width=100)
1367n/a self.tv.update()
1368n/a
1369n/a # assuming that the coords (5, 5) fall into heading #0
1370n/a simulate_heading_click(5, 5)
1371n/a if not success:
1372n/a self.fail("The command associated to the treeview heading wasn't "
1373n/a "invoked.")
1374n/a
1375n/a success = []
1376n/a commands = self.tv.master._tclCommands
1377n/a self.tv.heading('#0', command=str(self.tv.heading('#0', command=None)))
1378n/a self.assertEqual(commands, self.tv.master._tclCommands)
1379n/a simulate_heading_click(5, 5)
1380n/a if not success:
1381n/a self.fail("The command associated to the treeview heading wasn't "
1382n/a "invoked.")
1383n/a
1384n/a # XXX The following raises an error in a tcl interpreter, but not in
1385n/a # Python
1386n/a #self.tv.heading('#0', command='I dont exist')
1387n/a #simulate_heading_click(5, 5)
1388n/a
1389n/a
1390n/a def test_index(self):
1391n/a # item 'what' doesn't exist
1392n/a self.assertRaises(tkinter.TclError, self.tv.index, 'what')
1393n/a
1394n/a self.assertEqual(self.tv.index(''), 0)
1395n/a
1396n/a item1 = self.tv.insert('', 'end')
1397n/a item2 = self.tv.insert('', 'end')
1398n/a c1 = self.tv.insert(item1, 'end')
1399n/a c2 = self.tv.insert(item1, 'end')
1400n/a self.assertEqual(self.tv.index(item1), 0)
1401n/a self.assertEqual(self.tv.index(c1), 0)
1402n/a self.assertEqual(self.tv.index(c2), 1)
1403n/a self.assertEqual(self.tv.index(item2), 1)
1404n/a
1405n/a self.tv.move(item2, '', 0)
1406n/a self.assertEqual(self.tv.index(item2), 0)
1407n/a self.assertEqual(self.tv.index(item1), 1)
1408n/a
1409n/a # check that index still works even after its parent and siblings
1410n/a # have been detached
1411n/a self.tv.detach(item1)
1412n/a self.assertEqual(self.tv.index(c2), 1)
1413n/a self.tv.detach(c1)
1414n/a self.assertEqual(self.tv.index(c2), 0)
1415n/a
1416n/a # but it fails after item has been deleted
1417n/a self.tv.delete(item1)
1418n/a self.assertRaises(tkinter.TclError, self.tv.index, c2)
1419n/a
1420n/a
1421n/a def test_insert_item(self):
1422n/a # parent 'none' doesn't exist
1423n/a self.assertRaises(tkinter.TclError, self.tv.insert, 'none', 'end')
1424n/a
1425n/a # open values
1426n/a self.assertRaises(tkinter.TclError, self.tv.insert, '', 'end',
1427n/a open='')
1428n/a self.assertRaises(tkinter.TclError, self.tv.insert, '', 'end',
1429n/a open='please')
1430n/a self.assertFalse(self.tv.delete(self.tv.insert('', 'end', open=True)))
1431n/a self.assertFalse(self.tv.delete(self.tv.insert('', 'end', open=False)))
1432n/a
1433n/a # invalid index
1434n/a self.assertRaises(tkinter.TclError, self.tv.insert, '', 'middle')
1435n/a
1436n/a # trying to duplicate item id is invalid
1437n/a itemid = self.tv.insert('', 'end', 'first-item')
1438n/a self.assertEqual(itemid, 'first-item')
1439n/a self.assertRaises(tkinter.TclError, self.tv.insert, '', 'end',
1440n/a 'first-item')
1441n/a self.assertRaises(tkinter.TclError, self.tv.insert, '', 'end',
1442n/a MockTclObj('first-item'))
1443n/a
1444n/a # unicode values
1445n/a value = '\xe1ba'
1446n/a item = self.tv.insert('', 'end', values=(value, ))
1447n/a self.assertEqual(self.tv.item(item, 'values'),
1448n/a (value,) if self.wantobjects else value)
1449n/a self.assertEqual(self.tv.item(item, values=None),
1450n/a (value,) if self.wantobjects else value)
1451n/a
1452n/a self.tv.item(item, values=self.root.splitlist(self.tv.item(item, values=None)))
1453n/a self.assertEqual(self.tv.item(item, values=None),
1454n/a (value,) if self.wantobjects else value)
1455n/a
1456n/a self.assertIsInstance(self.tv.item(item), dict)
1457n/a
1458n/a # erase item values
1459n/a self.tv.item(item, values='')
1460n/a self.assertFalse(self.tv.item(item, values=None))
1461n/a
1462n/a # item tags
1463n/a item = self.tv.insert('', 'end', tags=[1, 2, value])
1464n/a self.assertEqual(self.tv.item(item, tags=None),
1465n/a ('1', '2', value) if self.wantobjects else
1466n/a '1 2 %s' % value)
1467n/a self.tv.item(item, tags=[])
1468n/a self.assertFalse(self.tv.item(item, tags=None))
1469n/a self.tv.item(item, tags=(1, 2))
1470n/a self.assertEqual(self.tv.item(item, tags=None),
1471n/a ('1', '2') if self.wantobjects else '1 2')
1472n/a
1473n/a # values with spaces
1474n/a item = self.tv.insert('', 'end', values=('a b c',
1475n/a '%s %s' % (value, value)))
1476n/a self.assertEqual(self.tv.item(item, values=None),
1477n/a ('a b c', '%s %s' % (value, value)) if self.wantobjects else
1478n/a '{a b c} {%s %s}' % (value, value))
1479n/a
1480n/a # text
1481n/a self.assertEqual(self.tv.item(
1482n/a self.tv.insert('', 'end', text="Label here"), text=None),
1483n/a "Label here")
1484n/a self.assertEqual(self.tv.item(
1485n/a self.tv.insert('', 'end', text=value), text=None),
1486n/a value)
1487n/a
1488n/a
1489n/a def test_selection(self):
1490n/a self.assertRaises(TypeError, self.tv.selection, 'spam')
1491n/a # item 'none' doesn't exist
1492n/a self.assertRaises(tkinter.TclError, self.tv.selection_set, 'none')
1493n/a self.assertRaises(tkinter.TclError, self.tv.selection_add, 'none')
1494n/a self.assertRaises(tkinter.TclError, self.tv.selection_remove, 'none')
1495n/a self.assertRaises(tkinter.TclError, self.tv.selection_toggle, 'none')
1496n/a
1497n/a item1 = self.tv.insert('', 'end')
1498n/a item2 = self.tv.insert('', 'end')
1499n/a c1 = self.tv.insert(item1, 'end')
1500n/a c2 = self.tv.insert(item1, 'end')
1501n/a c3 = self.tv.insert(item1, 'end')
1502n/a self.assertEqual(self.tv.selection(), ())
1503n/a
1504n/a self.tv.selection_set(c1, item2)
1505n/a self.assertEqual(self.tv.selection(), (c1, item2))
1506n/a self.tv.selection_set(c2)
1507n/a self.assertEqual(self.tv.selection(), (c2,))
1508n/a
1509n/a self.tv.selection_add(c1, item2)
1510n/a self.assertEqual(self.tv.selection(), (c1, c2, item2))
1511n/a self.tv.selection_add(item1)
1512n/a self.assertEqual(self.tv.selection(), (item1, c1, c2, item2))
1513n/a self.tv.selection_add()
1514n/a self.assertEqual(self.tv.selection(), (item1, c1, c2, item2))
1515n/a
1516n/a self.tv.selection_remove(item1, c3)
1517n/a self.assertEqual(self.tv.selection(), (c1, c2, item2))
1518n/a self.tv.selection_remove(c2)
1519n/a self.assertEqual(self.tv.selection(), (c1, item2))
1520n/a self.tv.selection_remove()
1521n/a self.assertEqual(self.tv.selection(), (c1, item2))
1522n/a
1523n/a self.tv.selection_toggle(c1, c3)
1524n/a self.assertEqual(self.tv.selection(), (c3, item2))
1525n/a self.tv.selection_toggle(item2)
1526n/a self.assertEqual(self.tv.selection(), (c3,))
1527n/a self.tv.selection_toggle()
1528n/a self.assertEqual(self.tv.selection(), (c3,))
1529n/a
1530n/a self.tv.insert('', 'end', id='with spaces')
1531n/a self.tv.selection_set('with spaces')
1532n/a self.assertEqual(self.tv.selection(), ('with spaces',))
1533n/a
1534n/a self.tv.insert('', 'end', id='{brace')
1535n/a self.tv.selection_set('{brace')
1536n/a self.assertEqual(self.tv.selection(), ('{brace',))
1537n/a
1538n/a self.tv.insert('', 'end', id='unicode\u20ac')
1539n/a self.tv.selection_set('unicode\u20ac')
1540n/a self.assertEqual(self.tv.selection(), ('unicode\u20ac',))
1541n/a
1542n/a self.tv.insert('', 'end', id=b'bytes\xe2\x82\xac')
1543n/a self.tv.selection_set(b'bytes\xe2\x82\xac')
1544n/a self.assertEqual(self.tv.selection(), ('bytes\xe2\x82\xac',))
1545n/a
1546n/a self.tv.selection_set()
1547n/a self.assertEqual(self.tv.selection(), ())
1548n/a
1549n/a # Old interface
1550n/a self.tv.selection_set((c1, item2))
1551n/a self.assertEqual(self.tv.selection(), (c1, item2))
1552n/a self.tv.selection_add((c1, item1))
1553n/a self.assertEqual(self.tv.selection(), (item1, c1, item2))
1554n/a self.tv.selection_remove((item1, c3))
1555n/a self.assertEqual(self.tv.selection(), (c1, item2))
1556n/a self.tv.selection_toggle((c1, c3))
1557n/a self.assertEqual(self.tv.selection(), (c3, item2))
1558n/a
1559n/a if sys.version_info >= (3, 7):
1560n/a import warnings
1561n/a warnings.warn(
1562n/a 'Deprecated API of Treeview.selection() should be removed')
1563n/a self.tv.selection_set()
1564n/a self.assertEqual(self.tv.selection(), ())
1565n/a with self.assertWarns(DeprecationWarning):
1566n/a self.tv.selection('set', (c1, item2))
1567n/a self.assertEqual(self.tv.selection(), (c1, item2))
1568n/a with self.assertWarns(DeprecationWarning):
1569n/a self.tv.selection('add', (c1, item1))
1570n/a self.assertEqual(self.tv.selection(), (item1, c1, item2))
1571n/a with self.assertWarns(DeprecationWarning):
1572n/a self.tv.selection('remove', (item1, c3))
1573n/a self.assertEqual(self.tv.selection(), (c1, item2))
1574n/a with self.assertWarns(DeprecationWarning):
1575n/a self.tv.selection('toggle', (c1, c3))
1576n/a self.assertEqual(self.tv.selection(), (c3, item2))
1577n/a with self.assertWarns(DeprecationWarning):
1578n/a selection = self.tv.selection(None)
1579n/a self.assertEqual(selection, (c3, item2))
1580n/a
1581n/a def test_set(self):
1582n/a self.tv['columns'] = ['A', 'B']
1583n/a item = self.tv.insert('', 'end', values=['a', 'b'])
1584n/a self.assertEqual(self.tv.set(item), {'A': 'a', 'B': 'b'})
1585n/a
1586n/a self.tv.set(item, 'B', 'a')
1587n/a self.assertEqual(self.tv.item(item, values=None),
1588n/a ('a', 'a') if self.wantobjects else 'a a')
1589n/a
1590n/a self.tv['columns'] = ['B']
1591n/a self.assertEqual(self.tv.set(item), {'B': 'a'})
1592n/a
1593n/a self.tv.set(item, 'B', 'b')
1594n/a self.assertEqual(self.tv.set(item, column='B'), 'b')
1595n/a self.assertEqual(self.tv.item(item, values=None),
1596n/a ('b', 'a') if self.wantobjects else 'b a')
1597n/a
1598n/a self.tv.set(item, 'B', 123)
1599n/a self.assertEqual(self.tv.set(item, 'B'),
1600n/a 123 if self.wantobjects else '123')
1601n/a self.assertEqual(self.tv.item(item, values=None),
1602n/a (123, 'a') if self.wantobjects else '123 a')
1603n/a self.assertEqual(self.tv.set(item),
1604n/a {'B': 123} if self.wantobjects else {'B': '123'})
1605n/a
1606n/a # inexistent column
1607n/a self.assertRaises(tkinter.TclError, self.tv.set, item, 'A')
1608n/a self.assertRaises(tkinter.TclError, self.tv.set, item, 'A', 'b')
1609n/a
1610n/a # inexistent item
1611n/a self.assertRaises(tkinter.TclError, self.tv.set, 'notme')
1612n/a
1613n/a
1614n/a def test_tag_bind(self):
1615n/a events = []
1616n/a item1 = self.tv.insert('', 'end', tags=['call'])
1617n/a item2 = self.tv.insert('', 'end', tags=['call'])
1618n/a self.tv.tag_bind('call', '<ButtonPress-1>',
1619n/a lambda evt: events.append(1))
1620n/a self.tv.tag_bind('call', '<ButtonRelease-1>',
1621n/a lambda evt: events.append(2))
1622n/a
1623n/a self.tv.pack()
1624n/a self.tv.wait_visibility()
1625n/a self.tv.update()
1626n/a
1627n/a pos_y = set()
1628n/a found = set()
1629n/a for i in range(0, 100, 10):
1630n/a if len(found) == 2: # item1 and item2 already found
1631n/a break
1632n/a item_id = self.tv.identify_row(i)
1633n/a if item_id and item_id not in found:
1634n/a pos_y.add(i)
1635n/a found.add(item_id)
1636n/a
1637n/a self.assertEqual(len(pos_y), 2) # item1 and item2 y pos
1638n/a for y in pos_y:
1639n/a simulate_mouse_click(self.tv, 0, y)
1640n/a
1641n/a # by now there should be 4 things in the events list, since each
1642n/a # item had a bind for two events that were simulated above
1643n/a self.assertEqual(len(events), 4)
1644n/a for evt in zip(events[::2], events[1::2]):
1645n/a self.assertEqual(evt, (1, 2))
1646n/a
1647n/a
1648n/a def test_tag_configure(self):
1649n/a # Just testing parameter passing for now
1650n/a self.assertRaises(TypeError, self.tv.tag_configure)
1651n/a self.assertRaises(tkinter.TclError, self.tv.tag_configure,
1652n/a 'test', sky='blue')
1653n/a self.tv.tag_configure('test', foreground='blue')
1654n/a self.assertEqual(str(self.tv.tag_configure('test', 'foreground')),
1655n/a 'blue')
1656n/a self.assertEqual(str(self.tv.tag_configure('test', foreground=None)),
1657n/a 'blue')
1658n/a self.assertIsInstance(self.tv.tag_configure('test'), dict)
1659n/a
1660n/a def test_tag_has(self):
1661n/a item1 = self.tv.insert('', 'end', text='Item 1', tags=['tag1'])
1662n/a item2 = self.tv.insert('', 'end', text='Item 2', tags=['tag2'])
1663n/a self.assertRaises(TypeError, self.tv.tag_has)
1664n/a self.assertRaises(TclError, self.tv.tag_has, 'tag1', 'non-existing')
1665n/a self.assertTrue(self.tv.tag_has('tag1', item1))
1666n/a self.assertFalse(self.tv.tag_has('tag1', item2))
1667n/a self.assertFalse(self.tv.tag_has('tag2', item1))
1668n/a self.assertTrue(self.tv.tag_has('tag2', item2))
1669n/a self.assertFalse(self.tv.tag_has('tag3', item1))
1670n/a self.assertFalse(self.tv.tag_has('tag3', item2))
1671n/a self.assertEqual(self.tv.tag_has('tag1'), (item1,))
1672n/a self.assertEqual(self.tv.tag_has('tag2'), (item2,))
1673n/a self.assertEqual(self.tv.tag_has('tag3'), ())
1674n/a
1675n/a
1676n/a@add_standard_options(StandardTtkOptionsTests)
1677n/aclass SeparatorTest(AbstractWidgetTest, unittest.TestCase):
1678n/a OPTIONS = (
1679n/a 'class', 'cursor', 'orient', 'style', 'takefocus',
1680n/a # 'state'?
1681n/a )
1682n/a default_orient = 'horizontal'
1683n/a
1684n/a def create(self, **kwargs):
1685n/a return ttk.Separator(self.root, **kwargs)
1686n/a
1687n/a
1688n/a@add_standard_options(StandardTtkOptionsTests)
1689n/aclass SizegripTest(AbstractWidgetTest, unittest.TestCase):
1690n/a OPTIONS = (
1691n/a 'class', 'cursor', 'style', 'takefocus',
1692n/a # 'state'?
1693n/a )
1694n/a
1695n/a def create(self, **kwargs):
1696n/a return ttk.Sizegrip(self.root, **kwargs)
1697n/a
1698n/atests_gui = (
1699n/a ButtonTest, CheckbuttonTest, ComboboxTest, EntryTest,
1700n/a FrameTest, LabelFrameTest, LabelTest, MenubuttonTest,
1701n/a NotebookTest, PanedWindowTest, ProgressbarTest,
1702n/a RadiobuttonTest, ScaleTest, ScrollbarTest, SeparatorTest,
1703n/a SizegripTest, TreeviewTest, WidgetTest,
1704n/a )
1705n/a
1706n/aif __name__ == "__main__":
1707n/a unittest.main()